使用vitest模拟了http请求的REST服务,但是为何不能axios请求成功?

我使用vitest模拟了http请求的REST服务:

// test/setup.ts

import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { HttpResponse, graphql, http } from 'msw'



const posts = [
  {
    userId: 1,
    id: 1,
    title: 'first post title',
    body: 'first post body',
  },
  // ...
]

export const restHandlers = [
  http.get('https://demo.example/path/to/posts', () => {
    return HttpResponse.json(posts)
  }),
]


const server = setupServer(...restHandlers)


//#region 生命周期内启动停止服务器
// 在所有测试之前启动服务器
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

// 所有测试后关闭服务器
afterAll(() => server.close())

// 每次测试后重置处理程序 `对测试隔离很重要`
afterEach(() => server.resetHandlers())

//#endregion 

// test/msw.test.ts

import { describe, expect, it } from "vitest";

import axios from 'axios';


describe('msw.test.ts', () => {
  it('shoudl worl', () => {

    // 发送 GET 请求
    axios.get('https://demo.example/path/to/posts')
    .then(response => {
      console.log(response.data);

      expect(response.data.length).toBe(2)
    })
    .catch(error => {
      console.error('发生错误:', error);
    });

  })
})

但是我运行:vitest的时候。

1、并没看到有:console.log(response.data); 这一行的执行呢?
2、请问是否是axios.get('https://demo.example/path/to/posts') 这个没有执行?

====

更新:
我使用async/await成功:

it('shoudl worl', async () => {

    // 发送 GET 请求
    const response = await axios.get('https://demo.example/path/to/posts')

请问,为何上述第一种方式不能成功呢?

阅读 613
avatarAI BotBETA

问题分析

在你提供的代码中,你使用了 msw(Mock Service Worker)来模拟 HTTP 请求,但在测试环境中可能遇到了一些配置或环境问题,导致 axios 请求未能成功被模拟服务器捕获。以下是一些可能的原因和解决方案:

  1. Mock Service Worker 未在客户端运行
    msw 默认是为浏览器环境设计的,它通过修改浏览器的网络请求来实现模拟。然而,在你的代码中,你使用了 msw/node,这通常用于 Node.js 环境中的模拟,但它不会自动拦截浏览器或 Node.js 脚本中的 HTTP 请求,除非你有额外的设置(如使用 worker.start() 在浏览器环境中)。
  2. 测试环境配置
    如果你的测试是在 Node.js 环境中运行的(如使用 Jest 或 Vitest 的 Node.js 模式),那么 msw 的配置需要确保在测试环境中正确启动和拦截请求。但是,对于 axios 这样的库,在 Node.js 中通常使用 httphttps 模块,而不是浏览器中的 fetchXMLHttpRequest,因此可能需要额外的适配器或设置。
  3. 异步测试处理
    在 Vitest 中,你的测试函数应该返回一个 Promise 或使用 async/await 来处理异步操作。你的测试函数没有返回 Promise,这可能导致 Vitest 无法等待异步操作完成就结束测试。

解决方案

1. 确保在正确的环境中使用 msw

如果你的测试是在浏览器环境中运行的(如通过 Vitest 的浏览器测试功能),确保你使用了 msw 的浏览器版本,并在测试环境中启动 worker.start()

2. 转换测试为异步

修改你的测试函数以返回 Promise 或使用 async/await

// test/msw.test.ts
import { describe, expect, it, vi } from "vitest";

import axios from 'axios';

describe('msw.test.ts', () => {
  it('should work', async () => {
    try {
      const response = await axios.get('https://demo.example/path/to/posts');
      console.log(response.data);

      expect(response.data.length).toBe(2);
    } catch (error) {
      console.error('发生错误:', error);
      expect(error).toBeUndefined(); // 或者其他适当的断言
    }
  });
});

3. 检查 msw 配置

如果你确实需要在 Node.js 环境中模拟 HTTP 请求,你可能需要使用如 node-fetchaxios-mock-adapter 这样的库来模拟请求,因为 msw 主要是为浏览器设计的。

4. 调试和日志

增加更多的日志输出,以查看请求是否确实被发送,以及是否有任何错误或异常被捕获。

通过以上步骤,你应该能够诊断并解决你的测试问题。如果问题仍然存在,请检查 msw 的文档和社区,以获取更多关于如何在你的特定环境中使用它的信息。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏