unit-testing - 使用 jest 和 vue-test-utils2 在 vue3 typescript 单元测试中模拟 axios (已解决)

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

我的组件调用

this.axios.get()

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

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

Cannot read property 'get' of undefined

并突出显示 this.axios 上的获取。

这是我期望的工作 ( 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 的,而不是像指南中那样直接访问。但是,由于我找不到任何与此相关的内容,我认为这无关紧要?

我也尝试像这样 mock 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() 来注入(inject)东西,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");
  });
});

最佳答案

使用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 }})
        }
      }
    }
  }
})

关于unit-testing - 使用 jest 和 vue-test-utils2 在 vue3 typescript 单元测试中模拟 axios (已解决),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66031298/

相关文章:

javascript - 如何更改Vue上Props的名称?

javascript - 在 Vue 动态添加的组件中添加和删除元素的问题

javascript - 如何用 Jest 覆盖(或模拟)类方法以测试函数?

javascript - Jest 在第一次失败后停止执行期望语句

.net - Azure DevOps 测试任务 : how to display messages during Visual Studio test execution

javascript - Chai 希望 .to.throw(Error) 无法按预期工作

python - python unittest 中的变量范围

javascript - Vuejs 和 Laravel 发送数据不起作用

javascript - Jest 测试运行 - 找不到模块错误

jestjs - jest.mock(..) 在 'describe' 中不起作用(TypeError : moduleName. split is not a function)