Vue test-utils如何测试router.push()

5 vue.js vue-router vue-test-utils

在我的组件中,我有一个方法将执行 router.push()

import router from "@/router";
// ...
export default {
  // ...
  methods: {
    closeAlert: function() {
      if (this.msgTypeContactForm == "success") {
        router.push("/home");
      } else {
        return;
      }
    },
    // ....
  }
}
Run Code Online (Sandbox Code Playgroud)

我想测试一下...

我写了以下规格

it("should ... go to home page", async () => {
    // given
    const $route = {
      name: "home"
    },
    options = {
      ...
      mocks: {
        $route
      }
    };
    wrapper = mount(ContactForm, options);
    const closeBtn = wrapper.find(".v-alert__dismissible");
    closeBtn.trigger("click");
    await wrapper.vm.$nextTick();
    expect(alert.attributes().style).toBe("display: none;")
    // router path '/home' to be called ?
  });
Run Code Online (Sandbox Code Playgroud)

1-我收到一个错误

console.error node_modules/@vue/test-utils/dist/vue-test-utils.js:15
[vue-test-utils]: could not overwrite property $route, this is usually caused by a plugin that has added the property asa read-only value
Run Code Online (Sandbox Code Playgroud)

2-如何编写Expect()以确保已调用此/ home路由

感谢您的反馈

Ser*_*eon 11

您正在做一些碰巧有效的事情,但我认为这是错误的,并且还会导致您在测试路由器时出现问题。您正在组件中导入路由器:

import router from "@/router";
Run Code Online (Sandbox Code Playgroud)

然后立即调用它push

router.push("/home");
Run Code Online (Sandbox Code Playgroud)

我不知道您究竟是如何安装路由器的,但通常您会执行以下操作:

new Vue({
  router,
  store,
  i18n,
}).$mount('#app');
Run Code Online (Sandbox Code Playgroud)

安装 Vue 插件。我敢打赌你已经在这样做了(事实上,这是暴露$route给你的组件的机制)。在示例中,还安装了一个 vuex 存储和对 vue-i18n 的引用。

这将$router您的所有组件中公开一个成员。push您可以从thisas调用它,而不是导入路由器并直接调用它$router

this.$router.push("/home");
Run Code Online (Sandbox Code Playgroud)

现在,这使得测试更容易,因为你可以在测试时通过mocks属性将一个假路由器传递给你的组件,就像你已经在做的那样$route

  const push = jest.fn();
  const $router = {
    push: jest.fn(),
  }
  ...
  mocks: {
    $route,
    $router,
  }
Run Code Online (Sandbox Code Playgroud)

然后,在你的测试中,你断言push没有被调用:

  expect(push).toHaveBeenCalledWith('/the-desired-path');
Run Code Online (Sandbox Code Playgroud)