使用 Jest 和酶测试 React Typescript 组件中的副作用

Testing side effects in React Typescript components with Jest and enzyme

我真的很想了解如何使用 React + TS 进行正确的单元测试,但到目前为止真的很艰难。我有两个非常简单的组件用于隔离事物。我将在底部包含组件,这样我就不会把东西弄得太乱。

很简单,点击Button,状态变量data中的'hello'变为'world'显示在InnerComponent中。 From everything I've seen,该模式是测试文档中的副作用,而不是尝试测试状态变化本身(谢天谢地,我有一次噩梦试图使用 Typescript 访问包装器实例中的状态).但是,eslint讨厌screen,TS找不到findByText。相反,我在下面的测试中注意到的行中收到错误 Property 'findByText' does not exist on type 'Screen'.ts(2339)

/* OuterComponent.test.tsx */
import { findByText } from '@testing-library/react';
import { mount } from 'enzyme';
import React from 'react';
import OuterComponent from './OuterComponent';

describe('OuterComponent', () => {
    it('does something on click', async () => {
        const wrapper = mount(<OuterComponent />);
        /* eslint-disable-next-line no-restricted-globals */
        expect(await screen.findByText('hello')).not.toBe(null); // error here
        wrapper.find('Button').simulate('click');
        /* eslint-disable-next-line no-restricted-globals */
        expect(await screen.findByText('world')).not.toBe(null); // error here
    });
});

这感觉像是一个非常标准的场景,那么你们这些使用 TS 的人如何测试这种类型的东西?这里是 OuterComponent:

/* OuterComponent.tsx */
import React, { useState } from 'react';
import { Button } from 'react-bootstrap';
import InnerComponent from './InnerComponent';

const initialData = 'hello';

const OuterComponent: React.FC = () => {
    const [data, setData] = useState<string>(initialData);

    const clickHandler = () => {
        if (data === 'hello') {
            setData('world');
        } else {
            setData('hello');
        }
    };

    return (
        <div className="Outer">
            <Button onClick={clickHandler}>Click</Button>
            <InnerComponent data={data} />
        </div>
    );
};

export default OuterComponent;

这里是 InnerComponent:

/* InnerComponent.tsx */
import React from 'react';
import { Card } from 'react-bootstrap';

interface TheseProps {
    data: string;
}

const InnerComponent: React.FC<TheseProps> = ({ data }) => {
    return (
        <div className="Inner">
            <Card>
                <Card.Text>{data}</Card.Text>
            </Card>
        </div>
    );
};

export default InnerComponent;

从“@testing-library/react”导出了一个单独的“屏幕”对象。具有 findByText 方法。不幸的是,您必须手动从库中抓取屏幕,因为当您没有明确导入时,自动导入只是认为它是全局“屏幕”。