使用 Jest 模拟我的函数的正确方法是什么?

问题描述 投票:0回答:1

我是 React/TypeScript 新手,需要单元测试方面的帮助。我需要对 ReactErrorBoundary.tsx 中的代码进行全行覆盖,但我的测试无法正确模拟对象。

ReactErrorBoundary.tsx:

export default function ReactErrorBoundary(props: { readonly children?: ReactNode }) {
  return (
    <ErrorBoundary
      FallbackComponent={ErrorPage}
      onError={(error) => {
        console.log("Error caught!");
        logger(error)
      }}
      onReset={() => {
        console.log("reloading the page...");
        window.location.reload();
      }}
    >
      {props.children}
    </ErrorBoundary>
  );
}

这是我的记录器(logService.tsx):

export const logger = (message: any) => {
    console.log("This is the logger service " +
      (message?.message ? message.message : message));
}

这些是我迄今为止所做的测试,其中只有前两个通过:

import ReactErrorBoundary from '../../components/ReactErrorBoundary';
import { ErrorBoundary } from 'react-error-boundary';
import { logger } from '../../services/logService';
import ErrorPage from '../../components/ErrorPage';

jest.mock('../../services/logService', () => ({
  logger: jest.fn(),
}));

jest.mock('react-error-boundary', () => {
  const React = require('react');
  const ErrorPage = require('../../components/ErrorPage').default;

  return {
    ...jest.requireActual('react-error-boundary'),
    ErrorBoundary: jest.fn(({ onError, onReset, FallbackComponent }) => {
      onError && onError(new Error());
      onReset && onReset();

      return {
        FallbackComponent: ErrorPage,
      };
    }),
  };
});

describe('ReactErrorBoundary', () => {
  test('renders ErrorBoundary with ErrorPage as FallbackComponent', () => {
    render(<ReactErrorBoundary />);
    expect(ErrorBoundary).toHaveBeenCalledWith({
        FallbackComponent: expect.any(Function),
        onError: expect.any(Function),
        onReset: expect.any(Function),
        children: undefined,
      }, {});            
  });

  test('passes children to ErrorBoundary', () => {
    const children = <div>Hello World</div>;

    render(<ReactErrorBoundary>{children}</ReactErrorBoundary>);
    expect(ErrorBoundary).toHaveBeenCalledWith({
      FallbackComponent: expect.any(Function),
      onError: expect.any(Function),
      onReset: expect.any(Function),
      children: <div>Hello World</div>,
    }, {});  
  });

  test('logs error message when onError is triggered', () => {
    const spy = jest.spyOn(console, 'log').mockImplementation();
    const error = new Error("Test error message");

    render(<ReactErrorBoundary><div>Error occurred!</div></ReactErrorBoundary>);
    
    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith('Error caught!', error);

    spy.mockRestore();
  });
});

当我运行第三个测试时,出现以下错误:

ReactErrorBoundary › logs error message when onError is triggered
expect(jest.fn()).toHaveBeenCalled()

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

我认为这是因为我在嘲笑react-error-boundary,但即使我修改了该模拟,它也不起作用。我将不胜感激任何帮助!

javascript reactjs typescript unit-testing jestjs
1个回答
0
投票

您必须使用

global
来访问全局上下文中的对象。

test('logs error message when onError is triggered', () => {
    const spy = jest.spyOn(global.console, 'log').mockImplementation();
    const error = new Error("Test error message");

    render(<ReactErrorBoundary><div>Error occurred!</div></ReactErrorBoundary>);
    
    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith('Error caught!', error);

    spy.mockRestore();
  });

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.