reactjs - 如何使用 Typescript 将 jest.spyOn 与 React 函数组件一起使用

标签 reactjs typescript jestjs enzyme ts-jest

我正在使用 Typescript 和 hooks 开发一个 React 应用程序,并且我正在尝试使用 Enzyme 和 Jest 来测试功能组件。我无法使用 jest.spyOn 来测试我的组件中的方法。 jest.spyOn 方法无法正确解析并在悬停时显示以下消息

"Argument of type '"validateBeforeSave"' is not assignable to parameter of type '"context" | "setState" | "forceUpdate" | "render" | "componentDidMount" | "shouldComponentUpdate" | "componentWillUnmount" | "componentDidCatch" | "getSnapshotBeforeUpdate" | ... 6 more ... | "UNSAFE_componentWillUpdate"'.ts(2345)"



我试图将实例转换为“任何”-
const instance = wrapper.instance() as any;

这当然忽略了编译时的问题,但是测试会抛出一个运行时错误,即组件上不存在函数。

Cannot spy the validateBeforeSave property because it is not a function; undefined given instead


// Some function Component

const SomeComponent = (props: IMyComponentProps) => {
  const { classes } = props;

  // Component has state
  const [count, setCount] = useState(0);

  function validateBeforeSave(){

  }

  function handleClick() {
  validateBeforeSave();
  .
  .
  .
  }

  return (
   <div>
      <Button>
      className="saveBtn"
      onClick={handleClick}
      </Button>
    </div>
  );

  };

  // Unit test
  describe('SomeComponent' () => {
  it('validates model on button click', () => {
      const wrapper = mount(
        <MuiThemeProvider theme={theme}>
          <SomeComponent/>
        </MuiThemeProvider>,
      );
  const instance = wrapper.instance();
      const spy = jest.spyOn(instance, "validateBeforeSave");
  wrapper
        .find('.saveBtn')
        .at(0)
        .simulate('click');
      expect(spy).toHaveBeenCalledTimes(1);
    });
  }

我在这里想念什么? spyOn 如何与函数组件一起工作?

我使用 create-react-app 模板创建了应用程序,它具有测试包的这些依赖项
"devDependencies": {
    "ts-jest": "^23.10.3",
    "@types/jest": "24.0.9",
    "@types/enzyme": "^3.9.1",
    "@types/enzyme-adapter-react-16": "^1.0.2",
    "enzyme": "^3.9.0",
    "enzyme-adapter-react-16": "^1.11.2",
    "enzyme-to-json": "^3.3.5",
  }

最佳答案

您的 validateBeforeSave函数在 SomeComponent 内声明使其成为外部无法访问的封闭/私有(private)范围功能。您可以将该函数作为 Prop 传递,然后您可以创建 spy 并将其作为 Prop 值在您的测试中传递,并测试传递的 Prop 函数( spy )是否被调用
所以你会修改你的函数有点像这样:

// some validator function
function validateBeforeSave(){
  ...
}

// Some function Component

const SomeComponent = (props: IMyComponentProps) => {
  const { classes, validateBeforeSave } = props;

  // Component has state
  const [count, setCount] = useState(0);


  function handleClick() {
  validateBeforeSave();
  .
  .
  .
  }

  return (
   <div>
      <Button>
      className="saveBtn"
      onClick={handleClick}
      </Button>
    </div>
  );

};
在你的单元测试中,像这样:
  // Unit test
  describe('SomeComponent' () => {
  it('validates model on button click', () => {
      const validateSpy = jest.fn();
      const wrapper = mount(
        <MuiThemeProvider theme={theme}>
          <SomeComponent validateSpy={validateSpy}/>
        </MuiThemeProvider>,
      );
      const instance = wrapper.instance();
      wrapper
        .find('.saveBtn')
        .at(0)
        .simulate('click');
      expect(validateSpy).toHaveBeenCalledTimes(1);
    });
  }

关于reactjs - 如何使用 Typescript 将 jest.spyOn 与 React 函数组件一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56297482/

相关文章:

javascript - 如何在 JavaScript 中表示代数数据类型和模式匹配

javascript - React 使用状态更新输入文本值并使其可变

node.js - 带有 Sequelize 的 typescript : UserAdmin.belongsTo 用不是 Sequelize.Model 的子类的东西调用

javascript - 如何在导出的 React 组件中注释 onChange 事件?

javascript - React Redux 调试 Prop

javascript - 模拟从另一个文件导入但仍返回模拟值

javascript - 我们如何与 npm start 或 npm build 一起运行 jest 单元测试?

javascript - 如何使用 Jest 在 typescript 中模拟 Date 对象?

javascript - 在 native 样式表中使用变量不会识别变量

javascript - 无法卸载 React 组件,从父组件返回 false