Categories
Testing

Jasmine — Custom Spies

Spread the love

Testing is an important part of JavaScript.

In this article, we’ll look at how to create custom spies.

Custom Spies

We can use the jasmine.setDefaultSpyStrategy to create a spy that does what we want.

For instance, we can write:

describe("spy tests", function () {
  beforeEach(function () {
    jasmine.setDefaultSpyStrategy(and => and.returnValue("Hello World"));
  }); 

  it('calls custom spy', function () {
    const spy = jasmine.createSpy();
    expect(spy()).toEqual("Hello World");
  });
});

We called setDefaultSpyStrategy with a callback that returns the 'Hello World' value.

Once we did that, our spy would return 'Hello world' .

So when we call spy , it returns 'Hello World' .

Also, we can call setDefaultSpyStrategy with no arguments to remove a custom default.

For instance, we can write;

describe("spy tests", function () {
  beforeEach(function () {
    jasmine.setDefaultSpyStrategy(and => and.returnValue("Hello World"));
  }); 

  it('calls custom spy', function () {
    const spy = jasmine.createSpy();
    expect(spy()).toEqual("Hello World");
  }); 

  it("throws if you call any methods", function () {
    jasmine.setDefaultSpyStrategy(and => and.throwError(new Error("Do Not Call Me")));
    const program = jasmine.createSpyObj(['start']);
    jasmine.setDefaultSpyStrategy(); expect(() => {
      program.start();
    }).toThrowError("Do Not Call Me");
  });
});

We called createSpyObj in the 2nd test to include a 'start' method in the porgram spy object.

Then we can check if an error is thrown with we call start .

Spying on Properties

We can spy on properties with the spyOnProperty method.

For instance, we can write:

describe("property spy test", function () {
  let someObject = {
    get myValue() {
      return 1
    }
  }; 

  beforeEach(function () {
    this.propertySpy = spyOnProperty(someObject, "myValue", "get").and.returnValue(1);
  }); 

  it("lets you change the spy strategy later", function () {
    this.propertySpy.and.returnValue(3);
    expect(someObject.myValue).toEqual(3);
  });
});

We created a someObject with the myValue getter to return something.

Then in the beforeEach hook, we call spyOnPropoerty spy on the object and return the mocked value we want.

In our test, we called returnValue to make the getter return another value.

And then we can check for the return value we just set.

We can also spy on an object with several properties on it by passing in a hash of properties.

For instance, we can write:

describe("property spy test", function () {
  it("lets you change the spy strategy later", function () {
    const obj = jasmine.createSpyObj("myObject", {}, { x: 3, y: 4 });
    expect(obj.x).toEqual(3); 
    Object.getOwnPropertyDescriptor(obj, "x").get.and.returnValue(7);
    expect(obj.x).toEqual(7);
  });
});

We create a spy object with some properties.

It has the x and y properties.

Then we can check for obj.x and return the value we want.

And then we can check for it.

Conclusion

There are different ways to spy on objects and return values.

We can create spy objects and set the spy strategy to what we want.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *