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

查看:2516
本文介绍了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()
  })
})

Login.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天全站免登陆