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

enzyme中containsMatchingElement方法不符合预期的问题咨询

Enzyme containsMatchingElement() 测试失败问题排查

问题场景

尝试使用Enzyme的containsMatchingElement()方法测试邮箱组件时,预期断言返回true,但实际返回false,怀疑是否正确使用了该方法。

组件代码(EmailField.tsx)

import React from "react";
type Props = {
  submitted: boolean;
  email: string;
  handleChange: React.ChangeEventHandler<HTMLInputElement>;
};
const EmailField = ({ submitted, email, handleChange }: Props) => {
  return (
    <React.Fragment>
      <input
        style={{ padding: "0.75em 1em" }}
        type="text"
        className="intro-x login__input input input--lg border border-gray-300 block"
        placeholder="Email"
        name="email"
        value={email}
        onChange={handleChange}
      />
      {submitted && !email ? (
        <h2 className="mt-1 text-theme-6">Email is required</h2>
      ) : null}
    </React.Fragment>
  );
};

export default EmailField;

测试代码

import { shallow, configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import EmailField from "./EmailField";

configure({ adapter: new Adapter() });

describe("rendering error message appropriately", () => {
  it("no error message", () => {
    let email = "z3376349@gmail.com";
    let handleChange = () => {};
    let submitted = true;
    const submittedAndEmailPresent = shallow(
      <EmailField submitted={submitted} email={email} handleChange={handleChange} />
    );

    expect(
      submittedAndEmailPresent.containsMatchingElement(
        <input
          style={{ padding: "0.75em 1em" }}
          type="text"
          className="intro-x login__input input input--lg border border-gray-300 block"
          placeholder="Email"
          name="email"
          value={email}
          onChange={handleChange}
        />
      )
    ).toEqual(true);
  });
});

问题原因

containsMatchingElement()会对JSX中的属性进行匹配,其中函数类型的属性会严格比较引用。测试代码中定义的handleChange是一个全新的函数,和组件接收的handleChange虽然逻辑相同,但引用地址不同,导致匹配失败。另外,containsMatchingElement()本身只需要匹配部分关键属性即可,不需要完全复刻所有属性。

解决方法

方法1:移除函数属性的匹配(推荐)

只保留输入框的核心属性进行匹配,比如type、name、value、placeholder等,忽略事件处理函数:

expect(
  submittedAndEmailPresent.containsMatchingElement(
    <input
      type="text"
      placeholder="Email"
      name="email"
      value={email}
    />
  )
).toEqual(true);

containsMatchingElement()会匹配所有指定的属性,同时忽略未指定的属性(比如style、className、onChange),只要组件中存在符合这些属性的元素,就会返回true。

方法2:复用同一个函数引用

如果一定要匹配onChange属性,可以确保测试中传递的函数和匹配时用的是同一个引用(其实这个没必要,因为我们不需要测试事件函数的引用,只需要确保组件正确接收并传递即可):

const handleChange = () => {}; // 提前定义,确保引用一致
const submittedAndEmailPresent = shallow(
  <EmailField submitted={submitted} email={email} handleChange={handleChange} />
);

expect(
  submittedAndEmailPresent.containsMatchingElement(
    <input
      // ...其他属性
      onChange={handleChange}
    />
  )
).toEqual(true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:45:34