ES6类开玩笑嘲弄

问题描述 投票:0回答:2

我有一个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
}
node.js ecmascript-6 jestjs
2个回答
1
投票

发生这种情况是因为您使用mockImplementation()而不是手动模拟或jest.mock()的工厂参数,并且模拟加载过程中正在创建模拟对象,因为构造函数调用不在任何函数内部。发生的事情是:

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

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

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

你也可以使用factory参数到jest.mock(),在那里指定实现,而不是调用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搞糊涂了。


0
投票

在为方法编写mockImplementation之前,您是否尝试过使用connection.mockClear();?另请参阅此https://jestjs.io/docs/en/es6-class-mocks

© www.soinside.com 2019 - 2024. All rights reserved.