【问题标题】:Mocking axios in a vue3 typescript unit test using jest and vue-test-utils2 (Solved)使用 jest 和 vue-test-utils 2 在 vue 3 typescript 单元测试中模拟 axios(已解决)
【发布时间】:2021-05-07 21:47:08
【问题描述】:

我的组件调用

this.axios.get()

当被挂载并将 vuex-store 变量传递给 api 时。 api返回一个数组作为响应,组件在与实际内容交换加载元素后显示一些返回的数据。

在我的单元测试中,我想模拟 axios-request 的结果,等待 loading- 和 content-element 之间的转换,然后最后检查内容的有效性。但是,测试失败并输出:

Cannot read property 'get' of undefined

并突出显示 this.axios 上的 get。

这是我期望的工作 (based on this guide):

... some imports etc. ...
const mockAxios = { whatIExpectToGet  };
jest.mock("axios", () => ({
  get: jest.fn(() => mockAxios)
}));
it("description of the test", async () => {
  const wrapper = mount(MyComponent);
... code continues ...

当然,我是通过这个访问 axios,而不是像他们在指南中那样直接访问。但是,由于我找不到任何与此相关的内容,我认为这无关紧要?

我自己也尝试过这样模拟 axios:

... imports etc. ...
const axios = {
  get: Promise.resolve({ whatIExpectToGet })
};
it("description of the test", async () => {
  const wrapper = mount(MyComponent, {
    global: {
      mocks: [ axios ]
    }
  });
... code continues ...

显然有类似问题的人使用 localVue.use() 来注入东西,but that's no longer supported

请有人如此善良和聪明,为我指明正确的方向吗? 谢谢。

-------------------> 解决方案

感谢tony 19,这个问题已经解决了。

我最终使用异步函数来模拟 axios,因为 Promise.resolve() 不适合我:

import { shallowMount, flushPromises } from "@vue/test-utils";
import MyComponent from "@/components/MyComponent.vue";

describe("MyComponent.vue", () => {
  const axios = {
    get: async () => ({
      data: { expectedData }
    })
  };
  it("test description", async () => {
    const wrapper = shallowMount(MyComponent, {
      global: {
        mocks: {
          axios: axios
        }
      }
    } as any);
    expect(wrapper.html()).toContain("some_string_i_display_while_loading");
    await flushPromises();
    expect(wrapper.html()).toContain("some_string_i_display_after_getting_the_response");
  });
});

【问题讨论】:

    标签: unit-testing vue.js jestjs axios vue-test-utils


    【解决方案1】:

    使用global.mocks 模拟axios 是正确的方法,但是您的尝试错误地使用了本应是对象的数组:

    const wrapper = mount(MyComponent, {
      global: {
        // mocks: [ axios ] ❌
        mocks: { axios } ✅
      }
    })
    

    注意axios.get() 解析为axios.Response 对象,该对象将响应数据存储在其data 属性中,因此您的模拟应该这样做。

    这是一个完整的例子:

    // MyComponent.vue
    export default {
      mounted() {
        this.axios.get('foo').then(resp => this.foo = resp.data)
      }
    }
    
    // MyComponent.spec.js
    it('gets foo', () => {
      const wrapper = mount(MyComponent, {
        global: {
          mocks: {
            axios: {
              get: Promise.resolve({ data: { foo: true }})
    
              // OR use an async function, which internally returns a Promise
              get: async () => ({ data: { foo: true }})
            }
          }
        }
      }
    })
    

    【讨论】:

      猜你喜欢
      • 2018-04-29
      • 2019-08-07
      • 2018-09-01
      • 2018-03-15
      • 2018-05-04
      • 2019-10-24
      • 2019-04-19
      • 2020-12-01
      • 1970-01-01
      相关资源
      最近更新 更多