使用自定义钩子测试组件

Testing component with custom hook

我在学习如何使用自定义挂钩测试 React 组件时遇到了困难。我认为这个问题与钩子模拟有关,但我不知道我做错了什么。我正在使用 jest 和 react-testing-library。

counter.js

import React from 'react';
import useCounter from 'hooks/useCounter/useCounter';

const Counter = props => {
  const {count, increment} = useCounter();

  return (
    <div>
      Counter: <span data-testid='counter-value'>{count}</span>
      <button onClick={increment} data-testid='increment'>+1</button>
    </div>
  );
};


export default Counter;

useCounter.js

import {useState} from 'react';

export default () => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);

  return {count, increment};
}

counter.test.js

import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './counter';

describe('counter.js', () => {
  const mockIncrement = jest.fn();

  jest.mock('hooks/useCounter/useCounter', () => {
    return jest.fn(() => ({
      count: 0,
      increment: mockIncrement,
    }))
  })

  it('should call counter increment', () => {
    render(<Counter/>);
    const buttonElement = screen.getByTestId('increment');
    fireEvent.click(buttonElement);

    expect(mockIncrement).toBeCalled();
  })
})

错误信息:

  ● counter.js › should call counter increment

    expect(jest.fn()).toBeCalled()

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

您不需要在测试期间模拟挂钩。您希望您的测试尽可能接近实际行为。

在这种情况下,只需点击按钮并检查计数值是否已更新为DOM中的预期值。

import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './counter';

describe('counter.js', () => {
    it('should increment count value on click', () => {
        render(<Counter/>);
        fireEvent.click(screen.getByRole('button', { name: '+1' }));
        expect(screen.getByTestId('counter-value')).toHaveTextContent('1');
    });
});