ES6类开玩笑

时间:2018-09-10 17:48:50

标签: node.js ecmascript-6 jestjs

我有一个ES6类,我需要模拟它的方法。按照文档的说明,我对此进行了手动模拟,并使构造函数被调用和声明。

我使用此类的函数只是一个运行类方法之一的基本函数。

test.js

const mockConnect = jest.fn();
const mockAccess = jest.fn();
jest.mock('../../src/connection');
const connection = require('../../src/connection').default;

connection.mockImplementation(() => {
  return {
    connect: mockConnect,
    access: mockAccess.mockReturnValue(true),
  };
});

caller_function(); 
expect(connection).toHaveBeenCalled(); // works properly as the constructor is called
expect(connection).toHaveBeenCalledWith('something'); // works
expect(mockAccess).toHaveBeenCalled(); // says it was not called when it should have

caller_function.js

import connection from 'connection';
const conn = new connection('something');

export function caller_function() {
  conn.access(); // returns undefined when mock says it should return true
}

2 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您使用mockImplementation()而不是手动模拟或jest.mock()的工厂参数,在模块加载期间创建了模拟对象进程,因为构造函数调用不在任何函数内。发生了什么事:

  1. 运行对jest.mock('../../src/connection')的调用并将connection设置为自动模拟。
  2. conn对象是使用自动模拟创建的。因此,其access方法返回未定义。
  3. 发生对mockImplementation()的调用,更改了connection模拟。但是,由于conn对象已经创建,因此无法获得自定义实现。

将构造函数调用移至caller_function是解决它的一种方法:

export function caller_function() {
  const conn = new connection('something');
  conn.access();
}

您还可以在jest.mock()中使用factory参数,在此处指定实现,而不用调用mockImplementation()。这样,您就不必更改实现代码:

const mockConnect = jest.fn();
const mockAccess = jest.fn();
import connection from '../../src/connection';
jest.mock('./so-import', () => {
  return jest.fn().mockImplementation(() => {
    return {
      connect: mockConnect,
      access: mockAccess.mockReturnValue(true)
    };
  });
});

...

顺便说一句,ES6类名称的约定以大写字母开头。我暂时被小写的connection弄糊涂了。

答案 1 :(得分:0)

在为方法编写嘲讽之前,您是否尝试过extern int[]? 另请参阅此https://jestjs.io/docs/en/es6-class-mocks