[英]How to unit test nested Actions in a Vue application?
I have a TypeScript-based Vue project with Jest as a test framework.我有一个以Jest作为测试框架的基于 TypeScript 的 Vue 项目。 I have Actions in a Module which I am trying to test.我正在尝试测试的模块中有操作。
My Actions look like this:我的操作如下所示:
@Action({})
saveSomeData (payload: any): Promise<any> {
const { isActive, id, routes } = payload
return this.context.dispatch('otherModule/createId', '', { root: true })
.then((id: string) => {
payload = { isActive, id, routes, type: 'postRoutes' }
return this.context.dispatch('submitRoutes', payload)
})
}
@Action({})
submitRoutes (payload: any): Promise<any> {
const { isActive, id, routes, type } = payload
return ActiveService.setActive(id)
.then(() => this.context.dispatch(type, { id, routes }))
}
Here is how my test looks like:这是我的测试的样子:
// Mocking createId in otherModule module to return ID
jest.mock('@/store/modules/otherModule', () => ({
createId: jest.fn(() => Promise.resolve([
{
id: 'someId'
}
]))
}))
...
describe('Testing save MyModule data', () => {
let store: any
beforeEach(() => {
store = new Vuex.Store({
modules: {
myModule,
otherModule
}
})
})
test('Should call createId and then call submitRoutes if ID is empty', async () => {
const payload = {
isActive: true,
id: '',
routes: []
}
const pld = {
isActive: true,
id: 'someId',
routes: [],
type: 'postRoutes'
}
store.dispatch = jest.fn()
await store.dispatch('myModule/saveSomeData', payload)
expect(store.dispatch).toHaveBeenCalledWith('myModule/saveSomeData', payload)
expect(store.dispatch).toHaveBeenCalledWith('otherModule/createId') // <-- here I get an error
expect(store.dispatch).toHaveBeenCalledWith('myModule/submitRoutes', pld)
})
})
Problem: My test fails and I haven't found any way to make it work.问题:我的测试失败了,我还没有找到任何方法让它工作。
The error:错误:
Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "otherModule/createId"
Received: "myModule/saveSomeData", {"id": "", "isActive": true, "routes": []}
Number of calls: 1
What I've tried我试过的
I've followed the Vuex documentation together with Jest , I also tried different solutions from the internet - unfortunately no luck.我和Jest一起关注了Vuex文档,我还尝试了来自互联网的不同解决方案 - 不幸的是没有运气。
I would appreciate any help.我将不胜感激任何帮助。
store.dispatch = jest.fn()
makes dispatch function a no-op, it isn't expected to call saveSomeData
and, therefore, dispatch other actions. store.dispatch = jest.fn()
使调度 function 成为无操作,它不应该调用saveSomeData
,因此调度其他操作。
This assertion isn't useful because it basically tests the previous line:这个断言没有用,因为它基本上测试了前一行:
expect(store.dispatch).toHaveBeenCalledWith('myModule/saveSomeData', payload)
store.dispatch
spy or stub isn't supposed to affect context.dispatch
in actions because the context is created on store initialization and already uses original dispatch
. store.dispatch
spy 或 stub 不应该影响操作中的context.dispatch
,因为上下文是在商店初始化时创建的并且已经使用原始dispatch
。 It may be unnecessary to do this because these are actions that should be tested, not Vuex itself.可能没有必要这样做,因为这些是应该测试的操作,而不是 Vuex 本身。
Actions can be spied on module level with jest.mock
and jest.requireActual
, or locally on Vuex module object if necessary.可以使用jest.mock
和jest.requireActual
在模块级别监视操作,或者在必要时在 Vuex 模块 object 上本地监视操作。 Module spies and mocks should happen on top level.模块间谍和模拟应该发生在顶层。 Object spies and mocks should happen prior to store instantiation. Object 间谍和模拟应该在存储实例化之前发生。
In this case a tested units are myModule
actions, ActiveService.setActive
and otherModule/createId
can be considered different units and should be mocked.在这种情况下,测试的单元是myModule
操作, ActiveService.setActive
和otherModule/createId
可以被认为是不同的单元并且应该被模拟。 If postRoutes
contains side effects, they can be mocked as well.如果postRoutes
包含副作用,它们也可以被模拟。
jest.spyOn(otherModule.actions, 'createId');
jest.spyOn(ActiveService, 'setActive');
store = new Vuex.Store(...)
...
otherModule.actions.createId.mockValue(Promise.resolve('stubbedId'));
ActiveService.setActive.mockValue(Promise.resolve());
await store.dispatch('myModule/saveSomeData', payload)
// assert otherModule.actions.createId call
// assert ActiveService.setActive call
// assert otherModule.actions.postRoutes call
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.