为什么我的 api return 模拟出现 404 错误?
Why does my mock of my api return a 404 error?
我使用 axios-mock-adapter
来模拟我的 API,它工作正常,但在一个模拟上 returns 出现 404 错误,我找不到原因。
有here带测试的沙箱,你可以看到当我们运行测试时,第二次检查失败,因为axios POST
调用没有被模拟。我尝试删除 header 部分,但是当我进行 运行 测试时沙箱崩溃了。
API 的模拟(测试部分):
import axios from "axios";
import MockAdapter from 'axios-mock-adapter';
import Utils from "../Utils/Utils";
// Global variable for post request with axios
global.users_post = axios.create({
baseURL: "http://localhost:5000/api/",
headers: {'Content-Type': 'application/json'}
});
/* Mockup API */
var userMock = new MockAdapter(users_post);
const user_resp_full = {
data: {
first_name: "Test",
last_name: "Test",
email: "test@gmail.com",
address: "Test",
zipcode: 1010,
city: "Test",
admin: false
}
}
const testAPI = () => {
userMock
.onPost("users", user_resp_full, Utils.getAuth())
.reply(200, {data: {status: "success"}});
}
test("something", async () => {
let tree = shallow(<UserManage type="create" uuid="" />);
testAPI();
await flushPromises();
// Some test
tree.find("#confirm-create").simulate("click");
await flushPromises();
// Error 404, mock isn't trigger
})
我已经检查过,数据相同,端点也相同,但似乎没有正确模拟它。
Axios 调用 class:
function (fields) {
users_post.post("users", fields, Utils.getAuth())
.then(resp => {
let data = resp.data;
// Do something
})
.catch(resp => {
let data = resp.response.data;
// Display error
});
}
此时,在我的 Jest 中测试它 returns 一个 404 错误,所以它没有模拟我的端点 API(其他作品)。
Utils.getAuth()
函数 returns 带有身份验证令牌的 header。
数据发送
关于数据发送的内容(首先是在使用mock进行测试调用之前,其次是在测试函数中,数据日志是发送到api的数据):
console.log src/tests/UserManage.test.js:222
POST USER 2
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
console.log src/Components/Users/UserManage.js:152
POST USER
console.log src/Components/Users/UserManage.js:153
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
更新
只有当我使用带有 header 的 POST
请求时才会发生此错误:
axios.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
我看到 on axios-mock-adapter github test page 最终我们应该在没有标签的情况下将 headers
放入测试中:
{headers: {Autorization: "Bearer token"}}
变成 {Autorization: "Bearer token"}
但不幸的是,它的效果并不比我好。
解决方案
在 Matt Carlotta 和他的 codesandbox 的回应下,我修改了 mine 2 个已修复问题的示例:
POST
使用 axios 请求 mock 的测试*
POST
使用 axios 实例请求模拟的测试*
* 与 axios-mock-adapter
好的,第二轮。
- 当
promise
需要一些时间响应时,您的 flushPromises
函数没有正确解析 promises
。解决方法是 return
和 promise
并在 .test.js
文件中在其前面粘贴一个 await
。由于我们在 promise
上使用 await
,因此不需要 await flushPromises()
。
- 此外,在
onPost
模拟函数中包含 headers
将导致函数抛出错误。由于您只是在模拟此请求(而不是实际测试其集成),因此您不需要包含它们。但是,由于您已经在使用自定义 axios
配置,因此您可以只在 axiosConfig.js
文件中包含 headers
。有关详细信息,请参阅代码和框的工作示例。
如下面的 Unit Testing
代码和框所示,如果您尝试在 deleteUserDataOverTime
方法上使用 await flushPromises()
,它会失败。它失败了,因为它没有解析 promise
。此 promise
需要一些时间来解决,并且没有得到妥善处理。
此外,由于测试的 asynchronous
性质,您不应在同一个测试文件中包含 unit
和 integration
测试。由于测试是 asynchronous
,在 相同的模拟请求 或 相同的模拟实例 [=70= 上调用 mockAxios.reset()
或 mockAxios.restore()
] -- 进行任何额外的真实或虚假 API 调用 -- 可能并且会无意中影响所有 API 调用(同样它们是异步的,而不是同步测试)。
单元测试 API 的工作示例:https://codesandbox.io/s/6z36z6pzyr(假 API -- 包括 GET
、PUT
、POST
和 DELETE
)
集成测试 API 的工作示例:https://codesandbox.io/s/7z93xnm206(真实的 API -- 仅包括 GET
,但PUT
、POST
和 DELETE
)
的功能应保持不变
codesandbox 的工作示例:https://codesandbox.io/s/526pj28n1n
好的,这是一个棘手的问题。问题出在 axios-mock-adapter 包上。它需要使用 .create()
方法的 axios 实例。
看这里:
creating an instance
在你的App.js中,
使用:
import axios from "axios";
const instance = axios.create();
instance.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
尽管在测试中不需要更改任何内容。
我从 axios-mock-adapter 的测试中得到提示。
例如:
post test
我使用 axios-mock-adapter
来模拟我的 API,它工作正常,但在一个模拟上 returns 出现 404 错误,我找不到原因。
有here带测试的沙箱,你可以看到当我们运行测试时,第二次检查失败,因为axios POST
调用没有被模拟。我尝试删除 header 部分,但是当我进行 运行 测试时沙箱崩溃了。
API 的模拟(测试部分):
import axios from "axios";
import MockAdapter from 'axios-mock-adapter';
import Utils from "../Utils/Utils";
// Global variable for post request with axios
global.users_post = axios.create({
baseURL: "http://localhost:5000/api/",
headers: {'Content-Type': 'application/json'}
});
/* Mockup API */
var userMock = new MockAdapter(users_post);
const user_resp_full = {
data: {
first_name: "Test",
last_name: "Test",
email: "test@gmail.com",
address: "Test",
zipcode: 1010,
city: "Test",
admin: false
}
}
const testAPI = () => {
userMock
.onPost("users", user_resp_full, Utils.getAuth())
.reply(200, {data: {status: "success"}});
}
test("something", async () => {
let tree = shallow(<UserManage type="create" uuid="" />);
testAPI();
await flushPromises();
// Some test
tree.find("#confirm-create").simulate("click");
await flushPromises();
// Error 404, mock isn't trigger
})
我已经检查过,数据相同,端点也相同,但似乎没有正确模拟它。
Axios 调用 class:
function (fields) {
users_post.post("users", fields, Utils.getAuth())
.then(resp => {
let data = resp.data;
// Do something
})
.catch(resp => {
let data = resp.response.data;
// Display error
});
}
此时,在我的 Jest 中测试它 returns 一个 404 错误,所以它没有模拟我的端点 API(其他作品)。
Utils.getAuth()
函数 returns 带有身份验证令牌的 header。
数据发送
关于数据发送的内容(首先是在使用mock进行测试调用之前,其次是在测试函数中,数据日志是发送到api的数据):
console.log src/tests/UserManage.test.js:222
POST USER 2
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
console.log src/Components/Users/UserManage.js:152
POST USER
console.log src/Components/Users/UserManage.js:153
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
更新
只有当我使用带有 header 的 POST
请求时才会发生此错误:
axios.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
我看到 on axios-mock-adapter github test page 最终我们应该在没有标签的情况下将 headers
放入测试中:
{headers: {Autorization: "Bearer token"}}
变成 {Autorization: "Bearer token"}
但不幸的是,它的效果并不比我好。
解决方案
在 Matt Carlotta 和他的 codesandbox 的回应下,我修改了 mine 2 个已修复问题的示例:
POST
使用 axios 请求 mock 的测试*POST
使用 axios 实例请求模拟的测试*
* 与 axios-mock-adapter
好的,第二轮。
- 当
promise
需要一些时间响应时,您的flushPromises
函数没有正确解析promises
。解决方法是return
和promise
并在.test.js
文件中在其前面粘贴一个await
。由于我们在promise
上使用await
,因此不需要await flushPromises()
。 - 此外,在
onPost
模拟函数中包含headers
将导致函数抛出错误。由于您只是在模拟此请求(而不是实际测试其集成),因此您不需要包含它们。但是,由于您已经在使用自定义axios
配置,因此您可以只在axiosConfig.js
文件中包含headers
。有关详细信息,请参阅代码和框的工作示例。
如下面的 Unit Testing
代码和框所示,如果您尝试在 deleteUserDataOverTime
方法上使用 await flushPromises()
,它会失败。它失败了,因为它没有解析 promise
。此 promise
需要一些时间来解决,并且没有得到妥善处理。
此外,由于测试的 asynchronous
性质,您不应在同一个测试文件中包含 unit
和 integration
测试。由于测试是 asynchronous
,在 相同的模拟请求 或 相同的模拟实例 [=70= 上调用 mockAxios.reset()
或 mockAxios.restore()
] -- 进行任何额外的真实或虚假 API 调用 -- 可能并且会无意中影响所有 API 调用(同样它们是异步的,而不是同步测试)。
单元测试 API 的工作示例:https://codesandbox.io/s/6z36z6pzyr(假 API -- 包括 GET
、PUT
、POST
和 DELETE
)
集成测试 API 的工作示例:https://codesandbox.io/s/7z93xnm206(真实的 API -- 仅包括 GET
,但PUT
、POST
和 DELETE
)
codesandbox 的工作示例:https://codesandbox.io/s/526pj28n1n
好的,这是一个棘手的问题。问题出在 axios-mock-adapter 包上。它需要使用 .create()
方法的 axios 实例。
看这里:
creating an instance
在你的App.js中, 使用:
import axios from "axios";
const instance = axios.create();
instance.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
尽管在测试中不需要更改任何内容。
我从 axios-mock-adapter 的测试中得到提示。
例如: post test