为啥我的 api 模拟返回 404 错误?

Posted

技术标签:

【中文标题】为啥我的 api 模拟返回 404 错误?【英文标题】:Why does my mock of my api return a 404 error?为什么我的 api 模拟返回 404 错误? 【发布时间】:2019-08-16 17:23:23 【问题描述】:

我使用axios-mock-adapter 模拟我的 API,它可以正常工作,但在一个模拟中它返回 404 错误,我找不到原因。

有here的沙箱有测试,你可以看到当我们运行测试时,第二次检查失败,因为axios POST调用没有被模拟。我试图删除标题部分,但是当我运行测试时沙箱刚刚崩溃。


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调用:

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 测试中,它返回 404 错误,因此它没有模拟我的端点 API(其他工作)。Utils.getAuth() 函数返回带有身份验证令牌的标头。


数据发送

这涉及数据发送的内容(首先是在使用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


更新

仅当我使用带有类似标头的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 和他的代码框的回复,我修改了 mine 并添加了 2 个已修复问题的示例:

使用 axios* 测试 POST 请求模拟 使用 axios* 实例对 POST 请求模拟的测试

* 与axios-mock-adapter

【问题讨论】:

可能完全不相关,但在您的 testApi 函数中,没有返回任何内容。实际上我看不到 testApi 函数的意义,如果你把你的 userMock.onPost()... 直接放在你的 test("something") 中呢? 感谢您的评论,我对此进行了测试,但不幸的是不起作用。我将该功能用于其他端点的其他模型并且它们可以工作。 您是否尝试过在 onPost 调用中添加前导斜杠 '/users' ?这些示例都显示前导斜杠,github.com/ctimmerm/axios-mock-adapter @N3SS4H 是的,但我使用在 baseURL 中具有..base url 的 axios 配置,例如 http://localhost:5000/,我对其进行了测试但不起作用。 【参考方案1】:

好的,第二轮。

promise 需要一些时间来响应时,您的flushPromises 函数无法正确解析promises。解决方法是 return promise 并在 .test.js 文件中将 await 粘贴在其前面。由于我们在promise 上使用await,因此不需要await flushPromises()。 另外,在onPost 模拟函数中包含headers 会导致函数抛出错误。由于您只是在模拟此请求(而不是实际测试其集成),因此您不需要包含它们。但是,由于您已经在使用自定义 axios 配置,因此您只需将 headers 包含在 axiosConfig.js 文件中即可。有关详细信息,请参阅您的代码框的工作示例。

如下面的Unit Testing 代码框所示,如果您尝试在deleteUserDataOverTime 方法上使用await flushPromises(),它会失败。它失败了,因为它没有解析promise。这个promise 需要一些时间才能解决,并且没有得到正确处理。

此外,由于测试的asynchronous 特性,您不应在同一测试文件中包含unitintegration 测试。由于测试是asynchronous,因此在相同的模拟请求相同的模拟实例上调用mockAxios.reset()mockAxios.restore()——进行任何额外的真实或虚假API调用-- 可以并且会无意中影响所有 API 调用(同样它们是异步的,而不是同步的测试)。

对 API 进行单元测试的工作示例:https://codesandbox.io/s/6z36z6pzyr(假 API -- 包括 GETPUTPOSTDELETE

集成测试 API 的工作示例:https://codesandbox.io/s/7z93xnm206(真正的 API -- 仅包括 GET,但对于 PUTPOST 和 @987654357,功能应该保持不变@)

您的代码框的工作示例:https://codesandbox.io/s/526pj28n1n

【讨论】:

您的回复对我的问题并没有真正的帮助,您使用GET 请求描述了测试,但没有人描述带有可能是错误的标头的POST 请求。但是,我将创建一个可以复制的测试。 是的,这很重要,因为我的GET 请求(在您的测试中也是如此)在我的测试中运行良好,但我的POST 请求并非如此,它都失败了。所以我搜索了POST 请求失败的原因,但我将用它创建一个沙盒测试。 我添加了一个沙盒链接。 请仔细阅读:API 实现测试(又名Unit Test)将模仿requestside effectresult。 API 集成测试(又名End to End Test)实际上将测试requestside effectresult 从客户端到API。我还更新了上面的答案以突出差异。 很确定我发现了你的问题。请参阅上面的更新答案。【参考方案2】:

好的,这是一个棘手的问题。问题出在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 的github 上一样,我将CodeSandbox 发送给您,更新了您的解决方案,但它不起作用。此外,我的问题已经使用了带有自定义配置的 axios 实例,并且也不起作用。

以上是关于为啥我的 api 模拟返回 404 错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的路线返回 404 错误 Laravel?

为啥 nginx 位置返回 404 错误?

为啥我在使用 Google Clas-s-room API 时会收到 404 错误?

为啥 Api Route 在 laravel 应用程序中不起作用,显示错误(未找到 404 错误)?

Windows Phone WEB API 通过 HttpClient 发布返回 404 错误

Paypal Refund Sale REST API 返回:远程服务器返回错误:(404)未找到