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

如何在Jest测试中动态修改fetchMock响应以测试条件渲染?

实现方案

你可以通过定义基础数据模板,结合在测试用例中动态修改响应的方式,避免重复配置fetchMock。下面提供两种实用的实现方式:

方式一:基于基础模板修改后重置fetchMock

这种方式适配所有fetchMock工具,核心是在beforeEach中配置默认的isBlack: true响应,在需要测试false场景的用例里,重新设置带有修改后数据的fetchMock:

describe('About', () => {
  // 定义基础数据模板,复用公共字段
  const baseAnimalData = {
    animal: 'cat',
    isBlack: true
  };

  beforeEach(() => {
    fetchMock.reset();
    // 配置默认的isBlack=true响应
    fetchMock.getOnce('/api/animals', { data: { ...baseAnimalData } });
    // 这里记得初始化组件实例,比如:instance = render(<About />);
  });

  afterEach(() => {
    expect(fetchMock.done()).toBe(true);
  });

  // isBlack=true的测试用例,直接使用默认配置
  it('should render "Black Cats are awesome" text', () => {
    expect(instance.getByText('Black Cats are awesome')).toBeVisible();
  });

  it('should render "Black Cats are my favourite" text', () => {
    expect(instance.getByText('Black Cats are my favourite')).toBeVisible();
  });

  it('should render "Black Cats rule" text', () => {
    expect(instance.getByText('Black Cats rule')).toBeVisible();
  });

  // 测试isBlack=false的场景
  it('should render no text when cat is not black', () => {
    // 重置fetchMock并设置新的响应
    fetchMock.reset();
    fetchMock.getOnce('/api/animals', { data: { ...baseAnimalData, isBlack: false } });
    // 重新渲染组件,确保获取新数据
    instance = render(<About />);
    
    // 断言所有目标文本都不存在
    expect(instance.queryByText('Black Cats are awesome')).toBeNull();
    expect(instance.queryByText('Black Cats are my favourite')).toBeNull();
    expect(instance.queryByText('Black Cats rule')).toBeNull();
  });
});

方式二:使用mockResponseOnce动态替换响应

如果使用的是jest-fetch-mock这类支持单次响应替换的工具,可以直接在测试用例中覆盖下一次请求的响应,无需完全重置fetchMock:

describe('About', () => {
  const baseAnimalData = {
    animal: 'cat',
    isBlack: true
  };

  beforeEach(() => {
    fetchMock.reset();
    // 配置默认的持久化响应
    fetchMock.get('/api/animals', { data: { ...baseAnimalData } });
    instance = render(<About />);
  });

  afterEach(() => {
    expect(fetchMock.done()).toBe(true);
  });

  // 正常场景测试
  it('should render "Black Cats are awesome" text', () => {
    expect(instance.getByText('Black Cats are awesome')).toBeVisible();
  });

  // isBlack=false场景
  it('should render no text when cat is not black', () => {
    // 替换下一次请求的响应
    fetchMock.mockResponseOnce(JSON.stringify({ 
      data: { ...baseAnimalData, isBlack: false } 
    }));
    // 重新触发组件的数据请求或重新渲染
    instance.rerender(<About />);
    
    expect(instance.queryByText('Black Cats rule')).toBeNull();
    expect(instance.queryByText('Black Cats are awesome')).toBeNull();
  });
});

核心要点

  • 复用基础数据模板,减少重复代码
  • 修改响应后必须重新渲染组件或触发数据刷新,确保组件获取到最新的isBlack值
  • 针对isBlack=false的测试,要断言所有相关文本都不存在,保证逻辑正确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:40:43