简体   繁体   English

如何使用 typescript 开玩笑地模拟 React.MemoExoticComponent (React.memo)

[英]How to mock a React.MemoExoticComponent (React.memo) with jest using typescript

In my project, I am using React + typescript and jest + Testing-Library/react for testing.在我的项目中,我使用 React + typescript 和 jest + Testing-Library/react 进行测试。 I am trying to mock a functional component wrapped in React.memo.我正在尝试模拟包装在 React.memo 中的功能组件。 With "normal" components I take this approach:对于“正常”组件,我采用这种方法:

jest.mock('../SearchComponent');

const mockSearchComponent = SearchComponent as jest.MockedFunction<
    typeof SearchComponent
>;

which then allows me to mock different implementations, eg然后允许我模拟不同的实现,例如

    mockSearchComponent.mockImplementation((props: Props) => {
        /* do something with props */
        return <div />;
    });

When attempting to do the same with a functional component wrapped in React.memo:当尝试对包装在 React.memo 中的功能组件执行相同操作时:

jest.mock('../PaginationComponent');
const mockPaginationComponent = PaginationComponent as jest.MockedFunction<
    typeof PaginationComponent
>;

mockPaginationComponent.mockImplementation(
        (props: PaginationComponentProps) => {
            return <div />;
        }
    );

VSCodium does not seem to find any problem with it, hovering over mockPaginationComponent, it shows VSCodium似乎没有发现任何问题,悬停在mockPaginationComponent上,它显示

const mockPaginationComponent: jest.MockedFunction<React.MemoExoticComponent<({ start, rows, toNumber, totalNumber, onPaginationUpdate, }: {
    start: number;
    rows: number;
    toNumber: number;
    totalNumber: number;
    onPaginationUpdate(start: number, rows: number): void;
}) => JSX.Element>>

However, when I run jest, I get the error但是,当我开玩笑时,我得到了错误

TypeError: mockPaginationComponent.mockImplementation is not a function

      88 |      };
      89 |
    > 90 |      mockPaginationComponent.mockImplementation(
         |                              ^
      91 |              (props: PaginationComponentProps) => {
      92 |                      return <div />;
      93 |              }

And when I remove the mockImplementation and instead try to eg expect a call to the mockPaginationComponent, such as:当我删除 mockImplementation 并尝试例如期望调用 mockPaginationComponent 时,例如:

renderWithRouter(<PersonSearch />);

            expect(mockPaginationComponent).not.toHaveBeenCalled();

I get the error:我得到错误:

    expect(received).not.toHaveBeenCalled()

    Matcher error: received value must be a mock or spy function

    Received has type:  object
    Received has value: {"$$typeof": Symbol(react.memo), "compare": null, "type": [Function mockConstructor]}

      261 |                     renderWithRouter(<PersonSearch />);
      262 |
    > 263 |                     expect(mockPaginationComponent).not.toHaveBeenCalled();
          |                                                         ^
      264 |

Am I missing something in my jest config?我在开玩笑的配置中遗漏了什么吗? Do I have to add another test layer to kindof mock the React.memo as well?我是否还必须添加另一个测试层来模拟 React.memo? I would have expected to be able mock the component wrapped in React.memo just like a "normal" component.我本来希望能够像“普通”组件一样模拟包装在 React.memo 中的组件。

I encountered the same issue, and I resolved it by exporting the component and the memo separately.我遇到了同样的问题,我通过分别导出组件和备忘录来解决它。

export const MyComponent: React.FC<MyProps> = (props: MyProps) => {};
export const MemoizedMyComponent = React.memo(MyComponent, compareFn)

in the implementation, use the memoized version在实现中,使用记忆化版本

return (
<div><MemoizedMyComponent props={props}/></div>
)

In the test, mock your non-memoized function as per usual and your test will simply memoize your mocked function instead.在测试中,像往常一样模拟你的非记忆 function ,你的测试将简单地记忆你模拟的 function 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM