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

React单元测试异常:brandId为2时type值未按预期变更

单元测试中brandId设置不生效问题排查

问题描述

React新手进行单元测试时遇到异常:预期当brandId为2时,页面中data-testid="article-card-type"的元素文本应为空,但测试用例始终通过,元素一直显示"model",修改测试中的brandId为2完全没有效果。

测试文件代码

jest.mock("companycomponents/presentation", () => ({
  PresentationContext: () => ({
    brandProductSection: {
      brandIds: 2,
    },
  }),
}));

test("type should be 'model' when brandId is 2", () => {
  const { getByTestId } = render(<Results />);
  const typeDiv = getByTestId("article-card-type");
  expect(typeDiv).toHaveTextContent("model");
});

业务代码片段

import {
  useDistributionContext,
} from "companycomponents/presentation";

export const Results: React.FC = () => {
  const [params, setParams] = useState<Record<string, string[]>>({});
  const [imageType, setImageType] = useState(model);
  const data = useResultPage(params);

  const context = useDistributionContext();
  const { brandIds} =
    context.brandProductSection;

  const handleChangeImageType = (data: ProductImageType) => {
    setImageType(data);
  };

const BRAND_ID = 1
const shouldHideSelector = !(
    data.length > 0 
    && (
        !brandIds 
        || (Array.isArray(brandIds) && !brandIds.includes(BRAND_ID))
    )
);

const typeString = shouldHideSelector ? `model` : "";


<div data-testid="article-card-type">{typeString}</div>

问题原因分析

  1. Mock对象不匹配:业务代码中使用useDistributionContext hook获取上下文,但测试代码里mock的是PresentationContext,两者不对应,导致业务代码根本拿不到测试中设置的brandId值。
  2. brandIds类型判断逻辑缺陷:业务代码判断brandIds是否为数组,而测试中设置的brandIds: 2是单个数字,Array.isArray(brandIds)返回false,导致!brandIds.includes(BRAND_ID)分支无法触发。此时!brandIds为!2即false,整个原条件data.length >0 && (...)结果为false,取反后shouldHideSelector为true,typeString始终是"model"。
  3. 测试用例预期错误:测试用例描述和预期结果矛盾,你预期brandId为2时文本为空,但测试用例却断言文本是"model",导致错误的测试结果判断。

解决步骤

  1. 修正Mock对象:将测试中的PresentationContext改为useDistributionContext,确保mock的是业务代码实际使用的hook:
jest.mock("companycomponents/presentation", () => ({
  useDistributionContext: () => ({
    brandProductSection: {
      brandIds: [2], // 改为数组格式,匹配业务代码的判断逻辑
    },
  }),
}));
  1. 调整brandIds格式:业务代码逻辑基于数组判断,测试中设置brandIds为数组[2];或修改业务代码兼容单个数字的情况:
// 业务代码中修改brandIds的处理
const processedBrandIds = Array.isArray(brandIds) ? brandIds : [brandIds];
const shouldHideSelector = !(
    data.length > 0 
    && (
        !brandIds 
        || !processedBrandIds.includes(BRAND_ID)
    )
);
  1. 修正测试用例预期:把测试用例的断言改为符合预期的结果:
test("type should be empty when brandId is 2", () => {
  const { getByTestId } = render(<Results />);
  const typeDiv = getByTestId("article-card-type");
  expect(typeDiv).toHaveTextContent("");
  // 或更严谨的断言:expect(typeDiv).not.toHaveTextContent("model");
});
  1. 确保data有数据:业务代码中data.length >0是条件之一,需mockuseResultPage返回有数据的结果,保证逻辑能走到判断brandId的分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:15:29