我如何检查笑话测试是否在派遣动作创建者中执行了一个派遣动作?
这是一个广义的例子:
// myActions.js
export const actionOne = () => (dispatch) => {
dispatch(actionTwo());
};
export const actionTwo = () => ({
type: 'SOME_TYPE',
});
我想测试是否已调用actionTwo
或已调度actionTwo
,理想情况下,该测试不知道actionTwo
发生了什么,因为我有一个不同的测试来处理该问题.
I would like to test that actionTwo
has been either called or dispatched, ideally without the test knowing anything about what is going on in actionTwo
, because I have a different test that takes care of that.
我正在使用redux-mock-store
将已测试的动作分发到模拟商店,并调用store.getActions()
来查找是否已分发了thunk动作创建者中的预期动作.我觉得这不是在这种情况下进行的正确方法,因为那样的话测试会测试更多的东西.我真的只想知道actionTwo
是否已被调用.
I am using redux-mock-store
to dispatch the tested action to a mocked store and calling store.getActions()
to find out if the expected actions within the thunk action creator have been dispatched. I feel it is not the right way to go in this particular scenario because then the test would test more than it should. I really only want to know if actionTwo
has been called at all.
我知道spyOn
和jest.mock
,但是我一直无法使用它们来解决我的问题.这是广义测试的样子:
I'm aware of spyOn
and jest.mock
, but I've been unable to use either to solve my problem. Here's what the generalized test looks like:
// myActions.test.js
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import * as actions from 'myActions';
const mockStore = configureMockStore([thunk]);
test('actionOne', () => {
const store = mockStore();
return store.dispatch(actions.actionOne()).then(() => {
// TODO: check if actions.actionTwo was called
});
});
test('actionTwo', () => {
const store = mockStore();
return store.dispatch(actions.actionTwo()).then(() => {
expect(store.getActions()).toEqual([{ type: 'SOME_TYPE' }]);
});
});
我很感谢任何建议!
花了我一段时间,但我发现了.这不是理想的方法(因为它涉及到已测试代码的微小更改),但是我可以获得的最接近理想的方法.
Took me a while, but I figured it out. It's not ideal (because it involves a small change to the tested code), but the closest to ideal that I could get.
// myActions.js
export const actionOne = () => (dispatch) => {
dispatch(exports.actionTwo());
};
export const actionTwo = () => ({
type: 'SOME_TYPE',
});
重要的更改是exports.actionTwo()
.这样,我确保可以从外部(测试文件)覆盖该函数的实现,并且覆盖函数实际上将在导入的文件中调用.
The important change is the exports.actionTwo()
. That way, I make sure that I can overwrite the function's implementation from the outside (the test file) and the overwriting function will actually be called from within the imported file.
现在,我可以简单地将以下内容添加到我的测试文件中:
Now I can simply add something like the following to my test file:
beforeEach(() => {
actions.actionTwo = jest.fn(() => () => Promise.resolve());
});
actionTwo
现在正在被嘲笑,我可以在其上使用toBeCalledWith
和其他期望.如果我想在同一测试文件中测试其实际实现,则可以在调用beforeEach
之前将其存储在变量中,例如:
actionTwo
is now being mocked and I can use toBeCalledWith
and other expectations on it. If I wish to test its actual implementation within the same test file, I can store it in a variable before calling beforeEach
, like:
const actionTwo = actions.actionTwo;
然后在其实现的测试设置中,我可以覆盖模拟调用
And then in the test setup for its implementation, I can overwrite the mock calling
actions.actionTwo = actionTwo;
就是这样.现在,我可以确保忽略导出函数的所有副作用,并将其作为实际单元进行测试.
That's it. Now I can make sure to ignore all side effects from an exported function and test it as an actual unit.