ES6类开玩笑的嘲笑 [英] ES6 class jest mocking
问题描述
我有一个ES6类,需要模拟它的方法.按照文档的说明,我对此进行了手动模拟,并使构造函数被调用和声明.
I have an ES6 class which I need to mock it's methods. Following the documentation i made a manual mock of this, and got the constructor to both be called and asserted.
我使用此类的函数只是一个运行类方法之一的基本函数.
My function that consumes this class is just a basic function that runs one of the class methods.
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
}
推荐答案
之所以发生这种情况,是因为您使用的是mockImplementation()
而不是手动模拟或jest.mock()
,和的工厂参数您的模拟对象是在模块加载过程中创建的,因为构造函数调用不在任何函数内部.发生了什么事:
This is happening because you're using mockImplementation()
instead of a manual mock or the factory parameter to jest.mock()
, and your mocked object is being created during the module loading process, since the constructor call is not inside of any function. What's happening is:
- 运行对
jest.mock('../../src/connection')
的调用并将connection
设置为自动模拟. -
conn
对象是使用自动模拟创建的.因此,它的access
方法返回undefined. - 对
mockImplementation()
的调用发生,更改了connection
模拟.但是,由于已经创建了conn
对象,因此无法获得自定义实现.
- The call to
jest.mock('../../src/connection')
runs and setsconnection
to be an automatic mock. - The
conn
object is created using the automatic mock. Therefore itsaccess
method returns undefined. - The call to
mockImplementation()
happens, changing theconnection
mock. However, since theconn
object has already been created, it doesn't get the custom implementation.
将构造函数调用移至caller_function
是修复它的一种方法:
Moving the constructor call into caller_function
is one way to fix it:
export function caller_function() {
const conn = new connection('something');
conn.access();
}
您还可以在jest.mock()
中使用factory参数,在此处指定实现,而不用调用mockImplementation()
.这样,您就不必更改实现代码:
You could also use the factory parameter to jest.mock()
, specifying the implementation there, instead of calling mockImplementation()
. That way you won't have to change your implementation code:
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
感到困惑.
BTW the convention for ES6 class names is to begin with an uppercase letter. I was temporarily confused by the lowercase name connection
.
这篇关于ES6类开玩笑的嘲笑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!