Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在Jest和Ezyme中激发和测试真实的粘贴事件(不是通过调用道具模拟的)_Reactjs_Unit Testing_Testing_Jestjs_Enzyme - Fatal编程技术网

Reactjs 如何在Jest和Ezyme中激发和测试真实的粘贴事件(不是通过调用道具模拟的)

Reactjs 如何在Jest和Ezyme中激发和测试真实的粘贴事件(不是通过调用道具模拟的),reactjs,unit-testing,testing,jestjs,enzyme,Reactjs,Unit Testing,Testing,Jestjs,Enzyme,我正在尝试对React应用程序中的一个非常简单的功能进行单元测试,通过在事件处理程序中添加event.preventDefault()阻止用户粘贴到文本区域,如下所示: function handlePaste(event) { event.preventDefault(); } // ... pass it down as props <TextareaComponent onPaste={handlePaste} /> 但是还没有找到一种有效的方法。任何帮助都将不胜

我正在尝试对React应用程序中的一个非常简单的功能进行单元测试,通过在事件处理程序中添加
event.preventDefault()
阻止用户粘贴到文本区域,如下所示:

function handlePaste(event) {
    event.preventDefault();
}

// ... pass it down as props

<TextareaComponent onPaste={handlePaste} />

但是还没有找到一种有效的方法。任何帮助都将不胜感激

由于您只是针对一个合成事件进行测试(而不是某种辅助操作,比如弹出窗口警告用户粘贴已禁用),因此最简单、正确的解决方案是模拟粘贴事件,向其传递模拟的
preventDefault
函数,然后断言调用了模拟函数

尝试对真实的粘贴事件进行断言是毫无意义的,因为这是React/Javascript实现(例如,断言在触发
onPaste
/
onChange
事件时调用回调函数)。相反,您需要测试调用回调函数的结果(在本例中,断言调用了
event.preventDefault
,如果没有调用,那么我们知道回调函数从未执行过!)

工作示例(单击
测试
选项卡运行断言):

为了简单起见,我只是断言输入最初为空,然后仅在触发
onChange
事件时更新值。这可以很容易地进行调整,以使某种传入的属性影响默认输入的


App.js

import React, { useCallback, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  const handleChange = useCallback(
    ({ target: { value } }) => setValue(value),
    []
  );

  const handlePaste = useCallback((e) => {
    e.preventDefault();
  }, []);

  const resetValue = useCallback(() => {
    setValue("");
  }, []);

  const handleSubmit = useCallback(
    (e) => {
      e.preventDefault();
      console.log(`Submitted value: ${value}`);
      setValue("");
    },
    [value]
  );

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="foo">
        <input
          id="foo"
          type="text"
          data-testid="test-input"
          value={value}
          onPaste={handlePaste}
          onChange={handleChange}
        />
      </label>
      <br />
      <button data-testid="reset-button" type="button" onClick={resetValue}>
        Reset
      </button>
      <button type="submit">Submit</button>
    </form>
  );
};

export default App;

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import App from "./App";

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

const value = "Hello";

describe("App", () => {
  let wrapper;
  let inputNode;
  beforeEach(() => {
    wrapper = mount(<App />);
    // finding the input node by a 'data-testid'; this is not required, but easier 
    // when working with multiple form elements and can be easily removed 
    // when the app is compiled for production
    inputNode = () => wrapper.find("[data-testid='test-input']");
  });

  it("initially displays an empty input", () => {
    expect(inputNode()).toHaveLength(1);
    expect(inputNode().props().value).toEqual("");
  });

  it("updates the input's value", () => {
    inputNode().simulate("change", { target: { value } });

    expect(inputNode().props().value).toEqual(value);
  });

  it("prevents the input's value from updating from a paste event", () => {
    const mockPreventDefault = jest.fn();
    const prefilledText = "Goodbye";

    // updating input with prefilled text
    inputNode().simulate("change", { target: { value: prefilledText } });

    // simulating a paste event with a mocked preventDefault
    // the target.value isn't required, but included for illustration purposes
    inputNode().simulate("paste", {
      preventDefault: mockPreventDefault,
      target: { value }
    });

    // asserting that "event.preventDefault" was called
    expect(mockPreventDefault).toHaveBeenCalled();

    // asserting that the input's value wasn't changed
    expect(inputNode().props().value).toEqual(prefilledText);
  });

  it("resets the input's value", () => {
    inputNode().simulate("change", { target: { value } });
    wrapper.find("[data-testid='reset-button']").simulate("click");

    expect(inputNode().props().value).toEqual("");
  });

  it("submits the input's value", () => {
    inputNode().simulate("change", { target: { value } });
    wrapper.find("form").simulate("submit");

    expect(inputNode().props().value).toEqual("");
  });
});
import React,{useCallback,useState}来自“React”;
常量应用=()=>{
const[value,setValue]=useState(“”);
const handleChange=useCallback(
({target:{value}})=>setValue(value),
[]
);
const handlePaste=useCallback((e)=>{
e、 预防默认值();
}, []);
const resetValue=useCallback(()=>{
设置值(“”);
}, []);
const handleSubmit=useCallback(
(e) =>{
e、 预防默认值();
log(`submittedvalue:${value}`);
设置值(“”);
},
[价值]
);
返回(

重置 提交 ); }; 导出默认应用程序;
App.test.js

import React, { useCallback, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  const handleChange = useCallback(
    ({ target: { value } }) => setValue(value),
    []
  );

  const handlePaste = useCallback((e) => {
    e.preventDefault();
  }, []);

  const resetValue = useCallback(() => {
    setValue("");
  }, []);

  const handleSubmit = useCallback(
    (e) => {
      e.preventDefault();
      console.log(`Submitted value: ${value}`);
      setValue("");
    },
    [value]
  );

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="foo">
        <input
          id="foo"
          type="text"
          data-testid="test-input"
          value={value}
          onPaste={handlePaste}
          onChange={handleChange}
        />
      </label>
      <br />
      <button data-testid="reset-button" type="button" onClick={resetValue}>
        Reset
      </button>
      <button type="submit">Submit</button>
    </form>
  );
};

export default App;

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import App from "./App";

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

const value = "Hello";

describe("App", () => {
  let wrapper;
  let inputNode;
  beforeEach(() => {
    wrapper = mount(<App />);
    // finding the input node by a 'data-testid'; this is not required, but easier 
    // when working with multiple form elements and can be easily removed 
    // when the app is compiled for production
    inputNode = () => wrapper.find("[data-testid='test-input']");
  });

  it("initially displays an empty input", () => {
    expect(inputNode()).toHaveLength(1);
    expect(inputNode().props().value).toEqual("");
  });

  it("updates the input's value", () => {
    inputNode().simulate("change", { target: { value } });

    expect(inputNode().props().value).toEqual(value);
  });

  it("prevents the input's value from updating from a paste event", () => {
    const mockPreventDefault = jest.fn();
    const prefilledText = "Goodbye";

    // updating input with prefilled text
    inputNode().simulate("change", { target: { value: prefilledText } });

    // simulating a paste event with a mocked preventDefault
    // the target.value isn't required, but included for illustration purposes
    inputNode().simulate("paste", {
      preventDefault: mockPreventDefault,
      target: { value }
    });

    // asserting that "event.preventDefault" was called
    expect(mockPreventDefault).toHaveBeenCalled();

    // asserting that the input's value wasn't changed
    expect(inputNode().props().value).toEqual(prefilledText);
  });

  it("resets the input's value", () => {
    inputNode().simulate("change", { target: { value } });
    wrapper.find("[data-testid='reset-button']").simulate("click");

    expect(inputNode().props().value).toEqual("");
  });

  it("submits the input's value", () => {
    inputNode().simulate("change", { target: { value } });
    wrapper.find("form").simulate("submit");

    expect(inputNode().props().value).toEqual("");
  });
});
从“React”导入React;
从“酶”导入{configure,mount};
从“酶-适配器-反应-16”导入适配器;
从“/App”导入应用程序;
配置({adapter:newadapter()});
const value=“你好”;
描述(“应用程序”,()=>{
让包装纸;
让输入节点;
在每个之前(()=>{
包装器=mount();
//通过“数据测试ID”查找输入节点;这不是必需的,但更简单
//使用多个表单元素时,可以轻松删除
//当应用程序被编译用于生产时
inputNode=()=>wrapper.find(“[data testid='test-input']”);
});
它(“最初显示一个空输入”,()=>{
expect(inputNode()).toHaveLength(1);
expect(inputNode().props().value).toEqual(“”);
});
它(“更新输入值”,()=>{
inputNode().simulate(“更改”,{target:{value}});
expect(inputNode().props().value).toEqual(value);
});
它(“防止从粘贴事件更新输入值”,()=>{
const mockPreventDefault=jest.fn();
const prefilledText=“再见”;
//使用预填充文本更新输入
inputNode().simulate(“更改”,{target:{value:prefilledText}});
//使用模拟的默认值模拟粘贴事件
//target.value不是必需的,但出于说明目的而包括在内
inputNode().simulate(“粘贴”{
preventDefault:mockPreventDefault,
目标:{value}
});
//断言调用了“event.preventDefault”
expect(mockPreventDefault).toHaveBeenCalled();
//断言输入的值没有更改
expect(inputNode().props().value).toEqual(prefilledText);
});
它(“重置输入值”,()=>{
inputNode().simulate(“更改”,{target:{value}});
查找(“[data testid='reset-button']”)。模拟(“单击”);
expect(inputNode().props().value).toEqual(“”);
});
它(“提交输入值”,()=>{
inputNode().simulate(“更改”,{target:{value}});
包装器。查找(“表单”)。模拟(“提交”);
expect(inputNode().props().value).toEqual(“”);
});
});

这很有道理,感谢您提供了非常全面的示例!