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
相关产品推荐
相关产品推荐

