React/Jest/Enzyme - 在 .toHaveBeenCalledWith(event) 检查中监视 changeHandler 失败

Posted

技术标签:

【中文标题】React/Jest/Enzyme - 在 .toHaveBeenCalledWith(event) 检查中监视 changeHandler 失败【英文标题】:React/Jest/Enzyme - Spying on changeHandler fails on .toHaveBeenCalledWith(event) check 【发布时间】:2021-05-13 10:30:36 【问题描述】:

Input.tsx

import React from "react";

export type InputProps = 
  name: string;
  label: string;
  value: any;
  onChange: React.FormEventHandler<htmlInputElement>;
;

export const Input = ( name, label, value, onChange : InputProps) => 
  return (
    <div>
      <label htmlFor=name>label</label>
      <input value=value name=name type="text" onChange=onChange />
    </div>
  );
;

Input.test.tsx

import React from "react";

import  mount  from "enzyme";
import  act  from "react-dom/test-utils";
import  Input, InputProps  from "./Input";

describe("Input tests", () => 
  test("renders without crashing", () => 
    const handleChange = jest.fn();

    const props: InputProps = 
      name: "login",
      label: "Your Login:",
      value: "",
      onChange: handleChange,
    ;

    const wrapper = mount(<Input ...props />);

    const mockEvent = 
      target: 
        value: "Administrator",
        name: "login",
      ,
     as React.ChangeEvent<HTMLInputElement>;

    act(() => 
      wrapper.find("input").simulate("change", mockEvent);
    );

    expect(handleChange).toHaveBeenCalledTimes(1);
    expect(handleChange).toHaveBeenCalledWith(mockEvent); // fails here
  );
);

.toHaveBeenCalledWith(mockEvent) 的最后一行失败并显示以下消息:

expect(jest.fn()).toHaveBeenCalledWith(...expected)

- Expected
+ Received

+ SyntheticBaseEvent 
+   "_dispatchInstances": null,
+   "_dispatchListeners": null,
+   "_reactName": "onChange",
+   "_targetInst": FiberNode 
+     "_debugHookTypes": null,

Sample codesandbox here

我试过了:

    onChange=onChange 更改为onChange=e =&gt; onChange(e)target: ... 更改为currentTarget: ...

但没有任何帮助。此时我不确定是因为我的输入是功能组件,还是版本有问题?任何帮助将不胜感激!

附:测试的目的是学习语法,而不是实现有意义的覆盖。

【问题讨论】:

【参考方案1】:

simulate 将您的模拟事件对象与来自ReactWrapperSyntheticEvent 对象合并(请参阅the documentation of simulate),因此相等性测试将失败。相反,您可以这样做:

expect(handleChange).toHaveBeenCalledWith(expect.objectContaining(mockEvent));

这不适用于currentTarget,因为SyntheticEvent 已经有一个属性currentTarget: null,所以在合并结果中它也将是null。对于target,它确实有效。这是通过测试的sandbox。

最好直接测试处理函数并远离simulate,因为它有点hacky并且不能真正模拟事件。它甚至似乎已被弃用:https://github.com/enzymejs/enzyme/issues/2173

【讨论】:

非常感谢您的宝贵时间!现在说得通了。通过阅读酶的问题跟踪器,我对其当前状态和与一般反应的兼容性感到震惊。伤心。 乐于助人!是的,javascript 生态系统的开源基础有时并不像我们希望的那样稳固:-)

以上是关于React/Jest/Enzyme - 在 .toHaveBeenCalledWith(event) 检查中监视 changeHandler 失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥 to_be_bytes() 和 to_le_bytes() 与我在这里期望的相反?

adjust to和adapt to有啥区别

Laravel 中的 Many-To-Many

在 Xamarin Forms App 中尝试 Speech-To-Text 后,Text-To-Speech 播放的音量非常低

如何在不使用 to_date /to_char 函数的情况下比较 oracle sql 中的日期?

在 row_to_json 函数中选择查询