Axios 捕获错误请求失败,状态码为 404 [英] Axios catch error Request failed with status code 404

查看:35
本文介绍了Axios 捕获错误请求失败,状态码为 404的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试一个使用 Axios 的登录组件.我尝试使用 axios-mock-adapter 模拟 Axios,但是当我运行测试时,它仍然出错:

I'm testing a login component that uses Axios. I tried mocking Axios with axios-mock-adapter, but when I run the tests, it still errors out with:

Error: Request failed with status code 404

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

How do I properly mock Axios in my tests?

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()
  })
})

登录.vue

doSigninNormal() {
  const formData = {
    email: this.email,
    password: this.password
  };
  this.$v.$touch()
  if (this.$v.$invalid ) {
    this.loading = false;
    this.emailLostFocus = true;
    this.passwordLostFocus = true;
    $('html, body').animate({scrollTop:110}, 'slow')

  } else {
    axios.post("/login", formData, {
      headers: { "X-localization": localStorage.getItem("lan") }
    })
    .then(res => {
      if (!res.data.result) {
        if (res.data.errors) {
          for (var i = 0; i < res.data.errors.length; i++) {
            this.$toaster.error(res.data.errors[i].message);
            if (
              res.data.errors[0].message == "Your email is not yet verified"
            ) {
              this.showVerificationLinkButton = true;
            }
            if (res.data.errors[i].field === "email") {
              this.$toaster.error(res.data.errors[i].message);
            }
            if (res.data.errors[i].field === "password") {
              this.$toaster.error(res.data.errors[i].message);
            }
          }
        }

        this.loading = false;
        this.$v.$reset();
      } else {
        this.loading = false;
        Raven.setUserContext({
          email: res.data.user.email,
          id: res.data.user.id
        });
        this.$store.dispatch("login", res);
        this.$v.$reset();
      }
    })
    .catch((err) => {
       console.log('catch', err);
    });
  }
}

推荐答案

测试错误的登录 URL

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

Testing wrong login URL

The root problem is the test code sets up axios-mock-adapter on a different URL than actually used in Login.vue, so the request is not stubbed:

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

// Login.vue
axios.post("/login", formData)
            ^^^^^^

修复方法是让测试代码使用相同的 URL(即 /login):

The fix is to make the test code use the same URL (i.e., /login):

// login.spec.js
mock.onPost("/login", formData).reply(200, fakeData)

需要等待 axios.post()

单元测试不会等待 POST 请求,因此测试将无法可靠地验证调用或响应(没有黑客攻击).

Need to await axios.post()

The unit test isn't awaiting the POST request, so the test wouldn't be able to reliably verify calls or responses (without a hack).

修复方法是更新 doSigninNormal() 以返回 axios.post() 承诺以允许调用者等待结果:

The fix is to update doSigninNormal() to return the axios.post() promise to allow callers to await the result:

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

// login.spec.js
await wrapper.vm.doSigninNormal()
expect(mock.history.post.length).toBe(1)

验证登录结果

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

Verifying login result

To verify the result, you could declare a local data prop to hold the login result 1️⃣, update doSigninNormal() to process the response (which is mocked with fakeData in the test), capturing the result 2️⃣. Then, just check that data property after awaiting 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)

这篇关于Axios 捕获错误请求失败,状态码为 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆