Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
Testing is an important part of JavaScript.
In this article, we’ll look at how to create more complex tests with Jasmine.
Array Checks
We can use the jasmine.arrayContaining
method to check the content of the array.
For example, we can write:
describe("jasmine.arrayContaining", function () {
let foo;
beforeEach(function () {
foo = [1, 2, 3];
});
it("matches arrays with some of the values", function () {
expect(foo).toEqual(jasmine.arrayContaining([3, 1]));
expect(foo).not.toEqual(jasmine.arrayContaining([6]));
});
describe("when used with a spy", function () {
it("is useful when comparing arguments", function () {
const callback = jasmine.createSpy('callback');
callback([1, 2, 3, 4]);
expect(callback)
.toHaveBeenCalledWith(
jasmine.arrayContaining([4, 2, 3])
);
expect(callback)
.not
.toHaveBeenCalledWith(
jasmine.arrayContaining([5, 2])
);
});
});
});
We have the jasmine.arrayContaining
method to check for the numbers in the array.
It returns true
if the array being checked has all the items in the array we passed into arrayContaining
.
We can do the same with function arguments.
String Matches
We can use the jasmine.stringMatching
to check if a string has a given substring or pattern.
For instance, we can write:
describe('jasmine.stringMatching', function () {
it("matches as a regex", function () {
expect({ foo: 'baz' })
.toEqual({
foo: jasmine.stringMatching(/^baz$/)
});
expect({ foo: 'foobarbaz' })
.toEqual({
foo: jasmine.stringMatching('bar')
});
});
describe("when used with a spy", function () {
it("is useful for comparing arguments", function () {
const callback = jasmine.createSpy('callback');
callback('foobarbaz');
expect(callback)
.toHaveBeenCalledWith(
jasmine.stringMatching('baz')
);
expect(callback)
.not
.toHaveBeenCalledWith(
jasmine.stringMatching(/^baz$/)
);
});
});
});
We have the jasmine.stringMatching
method with a regex and a string.
It lets us check for a regex pattern and a substring.
Asymmetric Equality Tester
We can create our own equality tester to do our check.
For instance, we can write:
describe("custom asymmetry", function () {
const tester = {
asymmetricMatch(actual) {
return actual.includes('bar');
}
};
it("dives in deep", function () {
expect("foo,bar,baz,quux").toEqual(tester);
});
describe("when used with a spy", function () {
it("is useful for comparing arguments", function () {
const callback = jasmine.createSpy('callback');
callback('foo,bar,baz');
expect(callback).toHaveBeenCalledWith(tester);
});
});
});
We created our own tester
object with the asymmericMatch
method to check for what we want.
We just return a boolean expression with the condition we want to check.
Then we can use it with the toHaveBeenCalledWith
or toEqual
.
Therefore, we can check for the values and the arguments.
Jasmine Clock
We can test time-dependent code with the jasmine.clock
method.
For example, we can write:
describe("custom asymmetry", function () {
let timerCallback;
beforeEach(function () {
timerCallback = jasmine.createSpy("timerCallback");
jasmine.clock().install();
});
afterEach(function () {
jasmine.clock().uninstall();
});
it("causes a timeout to be called synchronously", function () {
setTimeout(function () {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.clock().tick(101);
expect(timerCallback).toHaveBeenCalled();
});
});
We have the jasmine.clock().install()
to make Jasmine mock the time.
Then we call jasmine.clock().uninstall()
to remove the Jasmine clock.
In our test, we can change the time to what we want.
And then we can do our checks after some amount of time is elapsed.
Conclusion
We can test time-dependent code with Jasmine’s clock methods.
Also, we can check for array and string items with built-in functions.
And we can make our own matches to test what we want.