Jest 单元测试期间 Vue 路由器的注入失败

And*_* C. 5 vue.js jestjs vue-router

在具有 Composition API(和 Vue 3)的 .vue 文件中,设置路由器:

const router = useRouter()
Run Code Online (Sandbox Code Playgroud)

在玩笑测试中挂载 .vue 文件:

const wrapper = mount(Lookup)
Run Code Online (Sandbox Code Playgroud)

执行时,产生:

console.warn
    [Vue warn]: injection "Symbol([vue-router]: router)" not found.
      at <Anonymous ref="VTU_COMPONENT" >
      at <VTUROOT>
Run Code Online (Sandbox Code Playgroud)

模拟它会产生相同的输出:

useRouter().push = jest.fn()
Run Code Online (Sandbox Code Playgroud)

设置提供相同输出的结果:

import { useRouter } from 'vue-router'
...
const wrapper = mount(Lookup, {
  global: {
    plugins: [useRouter],
    provide: {
      router: {},
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

And*_* C. 11

这个解决方案允许我在 Jest 中进行模拟useRouter()。请注意,这是使用组合 API 的useRouter()唯一方法,因为不可用:vue-routerthis

const routerPushMock = jest.fn();

jest.mock('vue-router', () => ({
  useRouter: () => ({
    push: routerPushMock,
  }),
}));

test('...', async () => {
  const wrapper = mount(vueFile)
  ...
Run Code Online (Sandbox Code Playgroud)

  • 对于像我这样奋战了 3 个小时的人来说,需要注意的非常重要的一点是,你不能将 jest.mock() 放在 describe() 或 test() 内部,这样是行不通的。看起来 jest.mock() 应该位于规范文件的根目录中。 (7认同)
  • 谢谢@IgorNikiforov,这是非常有帮助的评论。虽然我花了 2 小时才读到你的评论:P (2认同)

uke*_*tar 8

如果有人还有这个错误

babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Run Code Online (Sandbox Code Playgroud)

我建议这样写

const mockPush = jest.fn();
jest.mock('vue-router', () => ({
  useRouter: () => ({
    push: mockPush,
  }),
}));
Run Code Online (Sandbox Code Playgroud)

给它命名(mockXYZ)很重要mockPush,因为根据: https: //github.com/facebook/jest/issues/2567,这个特定的命名是一个逃生舱口。