Besides its HTML fixture module, the Jasmine jQuery extension comes with a set of custom matchers, which help in writing expectations with elements in the DOM.
The biggest advantage of using these custom matchers, as demonstrated, is the better error messages they generate. So although you can write all your specs without using any of these matchers, doing so would get you much more useful information when an error happens.
To better understand this advantage, we can revisit the example of the spec should expose a property with its DOM element
. There, it uses the toExist
matcher:
it("should expose a property with its DOM element", function() {
expect(view.$el).toExist();
});
If this spec fails, we get a nice error message:
But if we rewrite this spec without the custom matcher (still making the same validation):
it("should expose a property with its DOM element", function() {
expect($(document).find(view.$el).length).toBeGreaterThan(0);
});
The error message gets less informative:
So use these matchers whenever you can to get better error messages. Let's go over some of the available custom matchers, demonstrated by example, with these acceptance criteria of the
NewInvestmentView
class:
NewInvestmentView
should allow the input of the stock symbolNewInvestmentView
should allow the input of sharesNewInvestmentView
should allow the input of the share priceNewInvestmentView
should have an empty stock symbolNewInvestmentView
should have its shares value at zeroNewInvestmentView
should have its share price value at zeroNewInvestmentView
should have its stock symbol input on focusNewInvestmentView
should not allow to addIt is important that you understand that these next examples, although useful to demonstrate how the Jasmine jQuery matchers work, are not really testing any JavaScript code, but only the HTML elements that were loaded by the HTML Fixture.
This checks if the element matches the passed CSS selector.
it("should allow the input of the stock symbol", function() {
expect(view.$el.find('.new-investment-stock-symbol')).toBe('input[type=text]'),
});
This checks if the content of the element matches the passed HTML.
it("should allow the input of shares", function() {
expect(view.$el).toContainHtml('<input type="number" class="new-investment-shares" name="shares" value="0">'),
});
This checks if the element contains any child element matching the passed CSS selector.
it("should allow the input of the share price", function() {
expect(view.$el).toContain('input[type=number].new-investment-share-price'),
});
Only valid for inputs, this validates the expected value against the element's value attribute.
it("should have an empty stock symbol", function() { expect(view.$el.find('.new-investment-stock-symbol')).toHaveValue(''), }); it("should have its shares value to zero", function() { expect(view.$el.find('.new-investment-shares')).toHaveValue('0'), });
This tests if the element has any attribute with the name and value specified. The following example shows how to use this matcher to test an input for its value attribute, an expectation that could have been written with the toHaveValue
matcher.
it("should have its share price value to zero", function() {
expect(view.$el.find('.new-investment-share-price')).toHaveAttr('value', '0'),
});
This checks if the input element is focused.
it("should have its stock symbol input on focus", function() {
expect(view.$el.find('.new-investment-stock-symbol')).toBeFocused();
});
This checks if the element is disabled.
it("should not allow to add", function() {
expect(view.$el.find('input[type=submit]')).toBeDisabled();
});
The extension has many more available matchers; be sure to check the documentation of the project at https://github.com/velesin/jasmine-jquery#jquery-matchers.