Jasmine — Test Array, Strings, and Time-Dependent Code
Tags: node, webdev, programming, testing
Published: 2021-01-23 20:52:49

**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.