javascript 用 Jest 模拟 ES6 类函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46500749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mocking an ES6 class function with Jest
提问by Imk
I have a question about how can I mock an ES6 class instance using Jest which is used by the method I actually want to test. My real case is trying to test a Redux async action creator that make a request and dispatch some action depending on the request result.
我有一个关于如何使用 Jest 模拟 ES6 类实例的问题,Jest 由我实际想要测试的方法使用。我的真实案例是尝试测试一个 Redux 异步操作创建器,该创建器发出请求并根据请求结果分派一些操作。
This is a simplified example of the use case :
这是用例的简化示例:
// communication.js
// An exported ES6 class module with proxy to the request library.
import post from './post';
export default class communication {
getData(data, success, error) {
const res = post(data);
if(res) {
success();
} else {
error();
}
}
}
// communicatorAssist.js
// A redux async function using communication.js
import communication from './communication';
// ...
export function retrieveData() {
return dispatch => {
const data = { name: 'michel'};
communication.getData(data,
(res) => dispatch(successAction(res)),
(res) => dispatch(errorAction(res));
}
}
// communicatorAssist.test.js testing the communicatorAssist
import { retrieveData } from 'communicatorAssist';
// communication.getData should call success callback
// for this test.
it('Should call the success callback', () => {
retrieveData();
// Assert that mocked redux store contains actions
});
// communication.getData should call error callback
// for this test.
it('Should call the error callback', () => {
retrieveData();
// Assert that mocked redux store contains actions
});
What I want is mocking the communication class in the test and change the behaviour of the getData()function in each test to call successand errorcallbacks without any call to post method.
我想要的是模拟测试中的通信类,并将getData()每个测试中函数的行为更改为调用success和error回调,而无需调用 post 方法。
I only success to mock the getData()function for the whole test file with this snippet at the top of it :
我只成功模拟了getData()整个测试文件的功能,并在其顶部使用此代码段:
import communication from '../communication'
jest.mock('../communication', () => (() => ({
getData: (success, error) => success()
})));
but I can't switch between implementation in different test case.
但我无法在不同测试用例的实现之间切换。
I figure that something using .mockImplementation()could do the stuff but I can't make this work in my case (I saw examples using it for module exporting functions but not for classes ).
我认为使用.mockImplementation()的东西可以做这些事情,但在我的情况下我无法做到这一点(我看到了将它用于模块导出功能但不是用于类的示例)。
Does anyone have an idea ?
有没有人有想法?
Edit:
编辑:
I forgot a part in the code exemple : the communication class instance creation which I think is the "problem" for mocking it :
我忘记了代码示例中的一部分:通信类实例创建,我认为这是嘲笑它的“问题”:
const com = new communication();
If comis instanciated at a global level in the communicatorAssist.js file : it fail with communication.getData is not a functionerror.
如果com在 communicatorAssist.js 文件中在全局级别实例化:它失败并显示communication.getData 不是函数错误。
But if I set the instanciation inside the retrieveData()function, Andreas K?berle snippet work's fine :
但是,如果我在retrieveData()函数内设置实例化,Andreas K?berle 片段就可以正常工作:
import communication from '../communication'
jest.mock('../communication', () => jest.fn());
communication.mockImplementation(
() => ({
getData: (success, error) => success()
})
)
(jest.mock()factory parameter need to return a function not directly jest.fn)
(jest.mock()工厂参数需要不直接返回一个函数jest.fn)
I don't know why it's not working using a file global scope instance.
我不知道为什么它不能使用文件全局作用域实例。
回答by Andreas K?berle
You need to mock the module with jest.fn()then you can import it and change the behaviour of it using mockImplementation:
您需要模拟模块,jest.fn()然后您可以导入它并使用mockImplementation以下方法更改它的行为:
import communication from '../communication'
jest.mock('../communication', jest.fn());
communication.mockImplementation(
() => ({
getData: (success, error) => success()
})
)

