React(Jest、Enzyme)单元测试:#mail元素className未更新问题
问题排查与解决方案
我一眼就注意到你的组件代码里有个容易忽略的小细节,这大概率就是测试失败的根源!
核心问题:className拼接缺少空格
看你组件里的className写法:
className={`solutions__mail-input${!readyToSend ? "--invalid" : ""}`}
当!readyToSend为true时,拼接后的类名会变成**solutions__mail-input--invalid**——这是一个完整的单一类名,而不是solutions__mail-input加上solutions__mail-input--invalid两个独立类。所以此时输入框的类名里根本不包含solutions__mail-input,你的断言自然会失败。
解决方案一:修正className拼接逻辑(推荐)
按照BEM规范的正确写法,应该给基础类和修饰类之间加一个空格,这样不管readyToSend状态如何,solutions__mail-input都会存在:
className={`solutions__mail-input ${!readyToSend ? "solutions__mail-input--invalid" : ""}`}
或者更健壮的写法(自动过滤空值):
className={[ "solutions__mail-input", !readyToSend && "solutions__mail-input--invalid" ].filter(Boolean).join(" ")}
解决方案二:调整测试断言(如果类名逻辑就是单一切换)
如果你确实想让类名在两种状态下切换(而非同时保留基础类),那需要根据readyToSend的预期状态修改断言:
// 假设合法邮箱输入后readyToSend会变为true expect(solutions.find("#mail").hasClass("solutions__mail-input")).toEqual(true); // 若校验是异步的,输入后readyToSend仍为false,则断言另一个类 // expect(solutions.find("#mail").hasClass("solutions__mail-input--invalid")).toEqual(true);
额外排查点:异步状态更新
如果validateMail()包含异步操作(比如调用API校验邮箱),模拟change事件后readyToSend的状态不会立即更新。这种情况下需要配合异步等待和组件更新:
it("test valid mail", async () => { const solutions = shallow(<Solutions />); const inputEmail = solutions.find("#mail"); inputEmail.simulate("change", { target: { value: "test@test.com", name: "mail" } }); // 等待异步操作完成 await new Promise(resolve => setTimeout(resolve, 0)); solutions.update(); // 强制组件同步状态 expect(solutions.find("#mail").props().value).toBe("test@test.com"); expect(solutions.find("#mail").hasClass("solutions__mail-input")).toEqual(true); });
内容的提问来源于stack exchange,提问作者Greed94
相关产品推荐
相关产品推荐

