Jest createSpyObj

2019-02-17 21:59发布

With Chai, you can create a spy object as follows:

chai.spy.object([ 'push', 'pop' ]);

With jasmine, you can use:

jasmine.createSpyObj('tape', ['play', 'pause', 'stop', 'rewind']);

What's the Jest equivalent?

Context: I am currently migrating a (typescript) Jasmine tests to (typescript) Jest. The migration guide is basically useless in this case: https://facebook.github.io/jest/docs/migration-guide.html As with any relatively new tech, there's nothing that can easily be found in the docs about this.

标签: jestjs
3条回答
Fickle 薄情
2楼-- · 2019-02-17 22:51
const video = {
  play() {
    return true;
  },
};

module.exports = video;

And the test:

const video = require('./video');

test('plays video', () => {
  const spy = jest.spyOn(video, 'play');
  const isPlaying = video.play();

  expect(spy).toHaveBeenCalled();
  expect(isPlaying).toBe(true);

  spy.mockReset();
  spy.mockRestore();
});

Docs found here: https://facebook.github.io/jest/docs/en/jest-object.html#jestspyonobject-methodname

There is also jest.fn()

const mockFn = jest.fn();
  mockFn();
  expect(mockFn).toHaveBeenCalled();

  // With a mock implementation:
  const returnsTrue = jest.fn(() => true);
  console.log(returnsTrue()); // true;

https://facebook.github.io/jest/docs/en/jest-object.html#jestfnimplementation

查看更多
做自己的国王
3楼-- · 2019-02-17 22:53

I've written a very quick createSpyObj function for jest, to support the old project. Basically ported from Jasmine's implementation.

export const createSpyObj = (baseName, methodNames): { [key: string]: Mock<any> } => {
    let obj: any = {};

    for (let i = 0; i < methodNames.length; i++) {
        obj[methodNames[i]] = jest.fn();
    }

    return obj;
};
查看更多
混吃等死
4楼-- · 2019-02-17 22:57

David's answer helped to get me on the right track. I modified it to work with ionic-mocks (https://github.com/stonelasley/ionic-mocks) in my Ionic3/Angular4 project.

In my test "helper" class, I have this:

export function  createSpyObj (baseName: string, methodNames: string[]): { [key: string]: jasmine.Spy } {
  const obj: any = {}
  for (let i: number = 0; i < methodNames.length; i++) {
    obj[methodNames[i]] = jasmine.createSpy(baseName, () => {})
  }
  return obj
}

Then I'm able to use it as such in my test/spec file. I inject the provider in question as:

{ provide: AlertController, useFactory: () => AlertControllerMock.instance() },

And until ionic-mocks is compatible with Jest, I have to copy over the mocks I want (which use createSpyObj):

class AlertMock {
  public static instance (): any {
    const instance: any = createSpyObj('Alert', ['present', 'dismiss'])
    instance.present.and.returnValue(Promise.resolve())
    instance.dismiss.and.returnValue(Promise.resolve())

    return instance
  }
}

class AlertControllerMock {
  public static instance (alertMock?: AlertMock): any {

    const instance: any = createSpyObj('AlertController', ['create'])
    instance.create.and.returnValue(alertMock || AlertMock.instance())

    return instance
  }
}
查看更多
登录 后发表回答