如何用Jest模拟实例化的对象

时间:2019-03-25 11:43:53

标签: javascript testing mocking jestjs

我有一个执行此操作的文件(src / dclient):

import DataClient from 'src/clients/data'

const DClient = new DataClient({ id: 'xxx' })
export default DClient

我有一个文件(正在尝试测试),可以执行以下操作:

import DClient from src/dclient

// Some code

DClient.alert('hello')

我正在尝试在Dclient.alert上写期望,但没有这样做。我试图将笑话测试设置为:

alertMock = jest.fn();
require('src/dclient').alert = alertMock

但是,即使我知道已调用alertMock.mock.calls,这也无法正常工作。我认为是因为dclient返回一个实例,并且实际上没有在其上定义警报。

我该如何设置这个玩笑,以便能在警惕状态下写下期望值?

2 个答案:

答案 0 :(得分:1)

有几种测试方法。

您尝试的方式运作良好,您只需将其更改为:

test('code', () => {
  const alertMock = jest.fn();
  require('src/dclient').default.alert = alertMock;  // <= mock alert on 'default'

  require('./code');  //  <= require the code that calls DClient.alert('hello')
  expect(alertMock).toHaveBeenCalledWith('hello');  // Success!
})

...因为src/dclient是具有default导出功能的ES6模块。


我可能会使用的方法是在alert类上模拟DataClient函数:

import DataClient from 'src/clients/data';

test('code', () => {
  const alertSpy = jest.spyOn(DataClient.prototype, 'alert');
  alertSpy.mockImplementation(() => {});

  require('./code');  //  <= require the code that calls DClient.alert('hello')
  expect(alertSpy).toHaveBeenCalledWith('hello');  // Success!
})

答案 1 :(得分:0)

Jest有一个制作精良的auto-mocking feature,它为导出对象上的每种方法生成jest.fn(),因此您可以:

import DClient from 'src/dclient'; // import the module
jest.mock('src/dclient'); // generate auto-mock

describe('alert', () => {
    beforeAll(() => {
        DClient.alert.mockReturnValue(true);
        // ^ not really needed in the alert case, but you'll get
        // error if the exported object doesn't have alert method
    });

    it('should have been called', () => {
        DClient.alert('hello');
        expect(DClient.alert).toHaveBeenCalledWith()
    });
});