返回

如何修复 Vue 3 中 `toHaveBeenCalled()` 断言失效的问题?

vue.js

在 Vue 3 中修复 toHaveBeenCalled() 断言

前言:

在 Vue 3 应用中进行单元测试时,toHaveBeenCalled() 断言可能不起作用。本文将深入探究这一问题并提供一个有效的解决方案。

问题剖析:

toHaveBeenCalled() 断言用于验证一个方法是否被调用过。在 Vue 2 中,它通过直接访问 vm 对象上的方法来实现。然而,在 Vue 3 中,vm 对象已弃用,方法现在通过 component.methods 访问。

解决方案:

要修复此问题,需要将断言更新为以下形式:

expect(wrapper.getComponent().methods.testFun).toHaveBeenCalled();

代码示例:

假设我们有一个 HelloWorld.vue 组件,其中有一个名为 testFun 的方法。以下是如何使用修复后的断言:

SPEC FILE:

import HelloWorld from "./HelloWorld.vue";
import { mount } from "@vue/test-utils";

describe("HelloWorld", () => {
  it("renders properly", () => {
    const wrapper = mount(HelloWorld);
    const testCall = jest.spyOn(wrapper.getComponent().methods, "testFun");

    wrapper.find("button").trigger("click");

    expect(testCall).toHaveBeenCalled();
  });
});

结论:

通过遵循本文中的步骤,开发人员可以轻松修复 Vue 3 应用中 toHaveBeenCalled() 断言不起作用的问题。通过使用 component.methods 来访问方法,断言将能够准确验证方法的调用。

常见问题解答:

Q1:为什么 vm 对象在 Vue 3 中被弃用了?
A:vm 对象在 Vue 3 中被弃用,以促进更清晰的 API 和更模块化的代码组织。

Q2:除了 toHaveBeenCalled() 之外,哪些其他断言也受到影响?
A:任何需要访问组件方法的断言都可能受到影响,例如 toHaveBeenCalledTimes()toBeCalledWith()

Q3:除了使用 component.methods 之外,还有其他访问方法的方法吗?
A:可以,还可以使用 instance() 方法访问组件实例并从中获取方法。

Q4:toHaveBeenCalled() 断言仍然是 Vue 3 中最常用的断言方式吗?
A:是的,toHaveBeenCalled() 仍然是 Vue 3 中验证方法调用最常用的断言方式。

Q5:为什么在更新断言时使用 getComponent() 而不是 wrapper
A:在某些情况下,wrapper 可能是一个 VueWrapper 对象,其中不包含 methods 属性。getComponent() 返回一个 Vue 对象,其中包含 methods 属性。