jest.spyOn返回Promise的方法

时间:2018-03-02 16:20:30

标签: node.js jestjs es6-promise

我正在尝试测试应用,但jest.spyOn让我发疯。

我正在研究节点v8.9.4和jest v22.2.2

我已经提取了这段代码:

// my-module.js
class MySingletonModule {
  constructor() {
    this.foo = 'bar';
  }
  myPromise() {
    return new Promise((resolve, reject) => resolve(this.foo));
  }
}

module.exports = new MySingletonModule();
// promise.test.js
const singleton = require('./my-module');
describe('Module test-suite', () => {
  let spy;

  beforeAll(async () => {
    spy = jest.fn();
    spy = jest.spyOn(singleton, 'myPromise');
  });

  beforeEach(() => spy.mockReset());

  test('Check bar', () => {
    return singleton.myPromise().then((bar) => {
      expect(bar).toEqual('bar');
    });
  });

  test('Check called times', () => {
    singleton.myPromise();
    expect(spy).toHaveBeenCalledTimes(1);
  });

  afterAll(() => {
    jest.restoreAllMocks();
  });
});

Check bar测试失败,因为myPromise方法未返回承诺:

the error

如果我评论spy = jest.spyOn(singleton, 'myPromise');测试工作..但显然其他测试不起作用..

enter image description here

我希望所有测试都适用于spyOn,因为阅读文档时写道:

  

注意:默认情况下,jest.spyOn也会调用spied方法。

我错过了什么?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我在文档中看不到这一点,但似乎jest允许你使用很多Jasmine的功能/语法,包括.and.callThrough

beforeEach(() => {
  spyOn(singleton, 'myPromise').and.callThrough();
};

test('Check bar', async () => {
  const bar = await singleton.myPromise();
  expect(bar).toEqual('bar');
});

test('Check called times', () => {
  singleton.myPromise();
  expect(singleton.myPromise.calls.count()).toBe(1);
});

以下是茉莉花间谍文档:https://jasmine.github.io/2.0/introduction.html#section-Spies

如果您想坚持使用已记录的jest.spyOn API,那么您可以在使用它的测试中设置间谍,这样它就不会影响另一个:

test('Check bar', async () => {
  const bar = await singleton.myPromise();
  expect(bar).toEqual('bar');
});

test('Check called times', () => {
  const spy = jest.spyOn(singleton, 'myPromise');
  singleton.myPromise();
  expect(spy).toHaveBeenCalledTimes(1);
});

答案 1 :(得分:0)

这是没有Jasmine的工作片段:

describe('Module test-suite', () => {
  let spy;

  beforeAll(() => { // get rid of async
    spy = jest.fn();
    spy = jest.spyOn(singleton, 'myPromise');
  });

  afterEach(() => spy.mockRestore()); // main difference is here

  test('Check bar', () => {
    return singleton.myPromise().then((bar) => {
      expect(bar).toEqual('bar');
    });
  });

  test('Check called times', () => {
    singleton.myPromise();
    expect(spy).toHaveBeenCalledTimes(1);
  });

  afterAll(() => {
    jest.restoreAllMocks();
  });
});

我认为最好使用mockRestore代替mockReset,因为据我所知jest docs mockReset几乎无法清除有关间谍和间谍对象的所有信息。并且mockRestore只清除一些临时数据,例如被叫次数。

为什么使用afterEach代替beforeEach很重要 - 我不知道:(

我也删除了async,因为测试失败了。