Axios 捕获错误请求失败,状态码为 404 [英] Axios catch error Request failed with status code 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屋!