【发布时间】:2021-12-21 17:23:01
【问题描述】:
上下文:
我们有一个自定义计时器,它会在用户闲置 15 分钟后注销。计时器的 performLogoff 函数调用 store.dispatch 到用户模块的注销操作,以清理我们的 Vue.js 应用程序中的其余状态和 localforage。
问题:
- 测试模拟
store.dispatch并调用performLogoff - performLogoff 调用
store.dispatch进行注销 - 问题 1:代码仍在
user/logout内部 - 后续问题 2:一旦遇到
user/logout中的第一个store.dispatch,它就会向下递归到自身并且永不终止
由于这些都是异步的,测试被标记为绿色/通过,但它不会终止。相反,它继续递归并最终耗尽内存,然后中止(见下面的输出)。
问题:
- 如何正确模拟
store.dispatch以便我们可以验证它是否已成功调用,而不会卡在此循环中?
timer.spec.js
import store from '@/store'
import userStore from '@/store/modules/user'
jest.mock('@/store')
...
let t
beforeAll(() => {
t = new Timer(...)
})
...
it('should be able to log user off', async () => {
jest.requireMock('@/store')
jest.requireMock('@/store/modules/user')
let count = 0
let mockCommit = () => {
count += 1
}
localforage.removeItem = jest.fn(() => { return null })
store.dispatch = jest.fn(async () => {
await userStore.actions.logout({ commit: mockCommit })
})
return t.performLogoff().then(() => {
expect(count).toBe(1)
})
})
timer.js
...
async performLogoff() {
await store.dispatch('user/logout')
}
...
存储/模块/user.js
...
async logout({ commit }) {
await localforage.removeItem('token')
await localforage.removeItem('user_details')
...
commit('SET_TOKEN', '')
commit('SET_USER_DETAILS', '')
...
store.dispatch('module2/setDetails', '')
store.dispatch('module3/setOtherDetails', '')
window.localStorage.clear()
}
...
测试控制台输出
<--- Last few GCs --->
[50123:0x7fd300008000] 152839 ms: Mark-sweep (reduce) 4081.6 (4143.1) -> 4081.1 (4143.6) MB, 5073.3 / 0.0 ms (average mu = 0.290, current mu = 0.001) allocation failure scavenge might not succeed
[50123:0x7fd300008000] 157867 ms: Mark-sweep (reduce) 4082.3 (4143.8) -> 4081.9 (4144.6) MB, 5023.3 / 0.0 ms (average mu = 0.168, current mu = 0.001) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 0x10f4cb70c node::Abort() [/usr/local/bin/node]
2: 0x10f4cc73d node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
3: 0x10f62b88d v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
4: 0x10f62b838 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
5: 0x10f76f9e7 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
6: 0x10f76e9e5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
7: 0x10f77ad0d v8::internal::Heap::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
8: 0x10f77ad6c v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
9: 0x10f752308 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
10: 0x10fa00771 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
11: 0x10f3304b9 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/usr/local/bin/node]
12: 0x10f3a8879 Builtins_NewStrictArgumentsElements [/usr/local/bin/node]
13: 0x1178a89d9
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
【问题讨论】:
标签: vue.js unit-testing jestjs vuex store