在 react-testing-library 中没有从 .toHaveBeenCalledTimes() 获得预期结果

Not getting expected result from .toHaveBeenCalledTimes() in react-testing-library

无论如何,尝试测试函数在触发后是否被调用。当我从该函数获得 console.log 时,fireEvent 正在工作。但是 .toHaveBeenCalledTimes(1) returns 0。我错过了什么?

如果我在父级中有 handleLoginSubmit 函数并将其作为道具传递给子级,那么在测试中一切都会通过。但如果它在同一个组件中,它就会失败。如果有任何意义,请使用打字稿。

已测试

import React, { FC } from 'react';

type Event = React.FormEvent<HTMLFormElement>;

interface Login {
  handleLoginSubmit?: (event: Event) => React.ReactNode;
}

const Login: FC<Login> = () => {
  const handleLoginSubmit = (_event: Event) => {
    console.log('Firing' ); // This is logged
  };

  return (
    <form data-testid='form' onSubmit={(event) => handleLoginSubmit(event)}>
      <input data-testid='email'/>
      <input data-testid='password'/>
      <button data-testid='login-button'>login</button>
    </form>
  );
};

export default Login;

我的提交测试

  it('should handle ClickEvents', () => {

    const handleLoginSubmit = jest.fn();

    const { getByTestId } = render(<Login/>);

    expect(getByTestId('login-button')).toBeTruthy();

    fireEvent.submit(getByTestId('form'));

    expect(handleLoginSubmit).toHaveBeenCalledTimes(1);

  });

错误信息

 ● Login page › should handle ClickEvents

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

      32 |     fireEvent.submit(getByTestId('form'));
      33 | 
    > 34 |     expect(handleLoginSubmit).toHaveBeenCalledTimes(1);
         |                               ^
      35 | 
      36 |   });
      37 | });

      at Object.it (__tests__/components/Login.test.tsx:34:31)

如果要直接调用handleLoginSubmit函数,则不能断言。因为它是在 Login SFC 的私有范围内定义的。你不能模拟或监视这个函数,因为你不能访问它。所以,你需要间接地测试它。由于您在此函数中使用了 console.log,我们可以侦测到 console.log。如果它被调用,则意味着 handleLoginSubmit 函数已被调用。

例如

index.tsx:

import React, { FC } from "react";

type Event = React.FormEvent<HTMLFormElement>;

interface Login {
  handleLoginSubmit?: (event: Event) => React.ReactNode;
}

const Login: FC<Login> = () => {
  const handleLoginSubmit = (_event: Event) => {
    console.log("Firing");
  };

  return (
    <form data-testid="form" onSubmit={event => handleLoginSubmit(event)}>
      <input data-testid="email" />
      <input data-testid="password" />
      <button data-testid="login-button">login</button>
    </form>
  );
};

export default Login;

index.spec.tsx:

import { render, fireEvent } from "@testing-library/react";
import Login from "./";
import React from "react";

it("should handle ClickEvents", () => {
  const logSpy = jest.spyOn(console, "log");
  const { getByTestId } = render(<Login />);
  expect(getByTestId("login-button")).toBeTruthy();
  fireEvent.submit(getByTestId("form"));
  expect(logSpy).toHaveBeenCalledTimes(1);
});

100% 覆盖率的单元测试结果:

 PASS  src/Whosebug/59162138/index.spec.tsx
  ✓ should handle ClickEvents (42ms)

  console.log node_modules/jest-mock/build/index.js:860
    Firing

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 index.tsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.987s, estimated 9s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/59162138