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

使用Jest测试Tailwind CSS React应用响应式设计失败,该如何解决?

响应式测试解决方案(TailwindCSS + Jest 环境)

方法1:手动模拟媒体查询匹配结果

jsDom 不会根据窗口尺寸变化自动更新媒体查询状态,所以可以直接 mock window.matchMedia 的返回值,让组件误以为当前处于目标断点。

示例代码:

// 测试前统一初始化mock
beforeEach(() => {
  Object.defineProperty(window, 'matchMedia', {
    writable: true,
    value: jest.fn().mockImplementation(query => ({
      matches: query === '(max-width: 639px)', // 对应Tailwind sm断点以下
      media: query,
      onchange: null,
      addListener: jest.fn(),
      removeListener: jest.fn(),
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      dispatchEvent: jest.fn(),
    })),
  });
});

test('移动端隐藏底部导航', () => {
  render(<App />);
  expect(screen.getByTestId("nav-bar-bottom")).not.toBeVisible();
});

test('桌面端显示底部导航', () => {
  // 重新mock为桌面端断点
  window.matchMedia = jest.fn().mockImplementation(query => ({
    matches: query === '(min-width: 640px)', // Tailwind sm及以上断点
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  }));
  
  render(<App />);
  expect(screen.getByTestId("nav-bar-bottom")).toBeVisible();
});

方法2:用第三方库简化媒体查询模拟

使用 jest-mock-media-queries 可以省去手动编写大量 mock 代码的麻烦:

  1. 安装依赖:
npm install jest-mock-media-queries --save-dev
  1. 测试用例示例:
import { mockMediaQueries } from 'jest-mock-media-queries';

describe('响应式导航测试', () => {
  const { useMediaQuery } = mockMediaQueries();

  test('移动端隐藏底部导航', () => {
    useMediaQuery('(max-width: 639px)', true);
    render(<App />);
    expect(screen.getByTestId("nav-bar-bottom")).not.toBeVisible();
  });

  test('桌面端显示底部导航', () => {
    useMediaQuery('(min-width: 640px)', true);
    render(<App />);
    expect(screen.getByTestId("nav-bar-bottom")).toBeVisible();
  });
});

方法3:改用真实浏览器测试(端到端方案)

如果需要完全模拟真实浏览器的响应式行为,避开 jsDom 的局限性,可以用 Cypress 或 Playwright 这类端到端工具:

Cypress 示例

it('移动端隐藏底部导航', () => {
  cy.viewport('iphone-6'); // 切换到指定移动端尺寸
  cy.visit('/');
  cy.get('[data-testid="nav-bar-bottom"]').should('not.be.visible');
});

it('桌面端显示底部导航', () => {
  cy.viewport(1280, 720); // 自定义桌面端尺寸
  cy.visit('/');
  cy.get('[data-testid="nav-bar-bottom"]').should('be.visible');
});

Playwright 示例

test('移动端隐藏底部导航', async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 667 });
  await page.goto('/');
  await expect(page.getByTestId('nav-bar-bottom')).not.toBeVisible();
});

核心说明

jsDom 的本质问题是不会根据 window.innerWidth 的修改自动重新计算 CSS 媒体查询的匹配状态,所以单纯修改尺寸、触发 resize 事件无效。必须通过模拟媒体查询结果,或者改用真实浏览器环境来验证响应式逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:02:06