Jasmine — Spies and Matchers
Tags: webdev, programming, javascript, testing
Published: 2021-01-23 20:52:30

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

### `createSpy`

We can call `createSpy` to stub a function.

They can be used to track arguments.

For instance, we can write:

```
describe("A spy", function () {
  let spy;

  beforeEach(function () {
    spy = jasmine.createSpy('spy');
    spy('foo', 'bar');
  });

  it("tracks that the spy was called", function () {
    expect(spy).toHaveBeenCalled();
  });
});
```

We created a spy with `jasmine.createSpy` .

It returns a function that can be watched with Jasmine.

So we can check if it has been called with `toHaveBeenCalled` .

### `createSpyObj`

We can use the `createSpyObj` method to create a mock with multiple spies.

For instance, we can write:

```
describe("Multiple spies", function () {
  let person;

  beforeEach(function () {
    person = jasmine.createSpyObj('person', ['eat', 'drink', 'sleep', 'walk']);
    person.eat();
    person.drink();
    person.sleep(0);
    person.walk(0);
  });

  it("creates spies for each requested function", function () {
    expect(person.eat).toBeDefined();
    expect(person.drink).toBeDefined();
    expect(person.sleep).toBeDefined();
    expect(person.walk).toBeDefined();
  });
});
```

We called `createSpyObj` with the spy name as the first argument.

And the methods available in the spy object in the 2nd argument.

Then we can it and then check if the methods are defined

### Matching and Spies

We can add more checks with more matches.

For instance, we can write:

```
describe("Tests", function () {
  it("matches any value", function () {
    expect({}).toEqual(jasmine.any(Object));
    expect(12).toEqual(jasmine.any(Number));
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const foo = jasmine.createSpy('foo');
      foo(12, () => true);
      expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function));
    });
  });
});
```

We have can use `toEqual` to check the type of a value with `jasmine.any` .

We can use `jasmine.any` with `toHaveBeenCalledWith` to check if a spy is called with a given type of data.

### jasmine.anything

We can use `jasmine.anythibng` to check if something matches anything that’s not `null` or `undefined` .

For instance, we can write:

```
describe("jasmine.anything", function () {
  it("matches anything", function () {
    expect(1).toEqual(jasmine.anything());
  });

  describe("when used with a spy", function () {
    it("is useful when the argument can be ignored", function () {
      const foo = jasmine.createSpy('foo');
      foo(12, 'bar');
      expect(foo).toHaveBeenCalledWith(12, jasmine.anything());
    });
  });
});
```

We have `jasmine.anything()` call to check if anything isn’t `null` or `undefined` .

### Checking Object Structure

We can check for object structure with the `jasmine.objectContaining` method.

For instance, we can write:

```
describe("jasmine.objectContaining", function () {
  let foo;

  beforeEach(function () {
    foo = {
      a: 1,
      b: 2,
      bar: "baz"
    };
  });

  it("matches objects with key-value pairs", function () {
    expect(foo).toEqual(jasmine.objectContaining({
      a: 1, bar: "baz"
    }));
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const callback = jasmine.createSpy('callback');

      callback({
        bar: "baz"
      });

      expect(callback)
        .toHaveBeenCalledWith(
          jasmine.objectContaining({
            bar: "baz"
          })
        );
    });
  });
});
```

We have the `jasmine.objectContaining` method to watch for object structure.

We just pass in the key-value pairs we want to check for.

It can be used with values and function arguments.

### Conclusion

We can check for values and objects and watch for spies with various Jasmine methods.