You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用MSW拦截Firebase API请求?React测试报错排查

React + MSW 拦截Firebase请求失败问题排查与解决

报错核心原因

  1. MSW拦截规则不匹配带查询参数的URL
    你的MSW Handler监听的是不带查询参数的https://travelsi-default-rtdb.firebaseio.com/posts.json,但实际请求带有?auth=USER-ACCESS-TOKEN参数,MSW默认精确匹配会跳过这类请求,导致拦截失败,触发真实网络请求报错。
  2. 测试用Redux Store未初始化accessToken
    报错信息显示请求URL的auth参数为空,说明测试时Redux的state.auth.userData.accessToken未赋值,生成了不合法的请求URL,进一步导致真实请求失败。
  3. MSW响应数据存在语法错误
    handlers.js的响应JSON中,id: p2是未定义变量(需改为字符串"p2"),且存在重复键名p1,这些语法错误会导致拦截成功后无法返回有效响应。

修复步骤

1. 修改MSW Handler,适配带查询参数的请求

MSW默认忽略URL查询参数进行匹配,只需修正响应数据的语法错误即可:

// handlers.js
import { rest } from 'msw';

export const handlers = [
  rest.get('https://travelsi-default-rtdb.firebaseio.com/posts.json', (req, res, ctx) => {
    // 可选:通过req.url.searchParams.get('auth')验证令牌
    return res(
      ctx.status(200),
      ctx.json({
        p1: {
          city: 'city 1',
          country: 'country',
          date: '01.01.2020',
          description: 'description',
          feelings: {
            f1: {
              reaction: 1,
            },
          },
          id: "p1",
          img: 'img',
          tag: '#tag',
          title: 'title 1',
        },
        p2: {
          city: 'city 2',
          country: 'country',
          date: '01.01.2020',
          description: 'description',
          feelings: {
            f1: {
              reaction: 1,
            },
          },
          id: "p2",
          img: 'img',
          tag: '#tag',
          title: 'title 2',
        },
      })
    );
  }),
];

2. 初始化测试用Redux Store的用户数据

测试时给Store注入带有效accessToken的初始状态,避免生成空参数的请求:

// AllPosts.test.js
import { screen, render, waitFor } from '@testing-library/react';
import AllPosts from './AllPosts';
import { Provider } from 'react-redux';
import { createStore } from '../../../../store/index';

describe('AllPosts component', () => {
  test('posts are rendered correctly', async () => {
    // 创建带初始登录状态的Store
    const store = createStore({
      auth: {
        userData: {
          accessToken: 'test-auth-token'
        }
      },
      posts: {
        postsToRender: []
      },
      ui: {}
    });

    render(
      <Provider store={store}>
        <AllPosts />
      </Provider>
    );

    // 使用RTL官方推荐的waitFor替代自定义延迟函数
    await waitFor(() => {
      expect(screen.getByText('city 1')).toBeInTheDocument();
    });
    screen.debug();
  });
});

3. 可选:给fetchPosts添加空值防护

避免accessToken为空时发起无效请求:

// fetchPosts.js
export const fetchPosts = accessToken => {
  return async dispatch => {
    if (!accessToken) {
      dispatch(
        uiActions.setNotification({
          status: 'error',
          type: 'get',
          message: '未获取到用户授权令牌',
        })
      );
      return;
    }
    // 原有的fetch逻辑...
  };
};

4. 验证拦截效果

在MSW Handler中添加日志,确认请求是否被成功拦截:

rest.get('https://travelsi-default-rtdb.firebaseio.com/posts.json', (req, res, ctx) => {
  console.log('MSW已拦截请求:', req.url);
  return res(/* ... */);
})

内容的提问来源于stack exchange,提问作者Maciej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:05:14