Axios捕获错误请求失败,状态码为404

pri*_*iya 5 unit-testing vue.js jestjs axios axios-mock-adapter

我正在测试使用Axios的登录组件。我尝试使用来模拟Axios axios-mock-adapter,但是当我运行测试时,仍然出现以下错误:

Error: Request failed with status code 404
Run Code Online (Sandbox Code Playgroud)

如何在测试中正确模拟Axios?

login.spec.js:

Error: Request failed with status code 404
Run Code Online (Sandbox Code Playgroud)

Login.vue

import Vue from 'vue'
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Login from '../../src/components/global/login/Login.vue';
import Raven from "raven-js";
import jQuery from 'jquery'
import Vuex from 'vuex'
import router from '../../src/router'
var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');

describe('Login.vue', () => {
  let wrapper;
  let componentInstance;
  let mock;
  beforeEach(() => {
    global.requestAnimationFrame = setImmediate,
    mock = new MockAdapter(axios)
    wrapper = shallowMount(Login, {
      router,
      $: jQuery,
      attachToDocument: true,
      mocks: {
        $t: () => { },
        Raven: Raven,
      },
      data() {
        return {
          email: '',
          password: '',
        }
      }
    })
    componentInstance = wrapper.vm;
  })

  afterEach(() => {
    mock.reset()
  })

  it('calls `axios()` with `endpoint`, `method` and `body`', async () => {
    const formData = {
      email: 'example@gmail.com',
      password: '111111'
    };

    let fakeData = { data: "fake response" }
    mock.onPost(`${process.env.VUE_APP_BASE_URL}/login/`, formData).reply(200, fakeData);

    wrapper.vm.email = 'example@gmail.com';
    wrapper.vm.password = '111111';
    wrapper.vm.doSigninNormal()
  })
})
Run Code Online (Sandbox Code Playgroud)

ton*_*y19 5

测试错误的登录URL

根本问题是测试代码axios-mock-adapter使用与实际使用的URL不同的URL 设置Login.vue,因此请求未存根:

// login.spec.js:
mock.onPost(`${process.env.VUE_APP_BASE_URL}/login/`, formData).reply(200, fakeData)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// Login.vue
axios.post("/login", formData)
            ^^^^^^
Run Code Online (Sandbox Code Playgroud)

解决方法是使测试代码使用相同的URL(即/login):

// login.spec.js
mock.onPost("/login", formData).reply(200, fakeData)
Run Code Online (Sandbox Code Playgroud)

需要等待axios.post()

单元测试不是在等待POST请求,因此该测试将无法可靠地验证调用或响应(没有hack)。

解决方法是更新doSigninNormal()以返回axios.post()允许呼叫者等待结果的承诺:

// Login.vue
doSigninNormal() {
  return axios.post(...)
}

// login.spec.js
await wrapper.vm.doSigninNormal()
expect(mock.history.post.length).toBe(1)
Run Code Online (Sandbox Code Playgroud)

验证登录结果

为了验证结果,您可以声明一个本地数据prop来保存登录结果1 ??,更新doSigninNormal()以处理响应(fakeData在测试中模拟),捕获结果2 ??。然后,只需在等待之后检查该数据属性doSignInNormal()

// Login.vue
data() {
  return {
    ...
    result: '' 1??
  }
}
methods: {
  doSignInNormal() {
    return axios.post(...)
            .then(resp => this.result = resp.data.result) 2??
  }
}

// login.spec.js
const result = await wrapper.vm.doSigninNormal()
expect(result).toBe(fakeData.result)
expect(wrapper.vm.result).toBe(fakeData.result)
Run Code Online (Sandbox Code Playgroud)

使用axios-mock-adapter编辑模拟Axios呼叫