react-test-renderer 的 create() 与 @testing-library/react 的 render()

IT技术 reactjs react-testing-library react-test-renderer
2021-05-13 14:09:08

我是 React 的新手,对所有测试库都感到困惑。我让我的测试代码正常工作,但必须create()从 react-test-renderer调用才能使用它似乎是多余的,toMatchSnapshot()并且必须render()从 @testing-library/react调用才能使用其断言,例如getByLabelText().

import {render} from '@testing-library/react';
import {act, create} from 'react-test-renderer';

it('renders a login screen', () => {
    let mockInitialState: AppState = {
        auth: initialAuthState
    };

    let component = <Root initialState={mockInitialState}/>;

    let tree = null;
    act(() => {
        tree = create(component);
    });
    expect(tree).toMatchSnapshot();

    const {getByLabelText, getByText} = render(component);
    expect(getByLabelText(/Email Address.*/));
    expect(getByLabelText(/Password*/));
    expect(getByText('Sign in'));
});

作为一个新手,我很难理解所有这些 React 库之间的区别。但我认为必须有一种更简单的方法。

如何简化我的测试代码,以便我只需要调用呈现组件的一件事,以便我可以进行快照测试和更具体的断言?

2个回答

我从 Codementor.io 的 Ziad Saab 那里得到了答案:

  • create() 允许您针对虚拟 DOM(即“React DOM”)进行测试

  • render()来自react测试库并呈现您的树,但也允许您拥有所有 get*() 断言。它允许您针对 DOM 进行测试。

下面是如何简化代码:

it('renders a login screen', () => {
    let mockInitialState: AppState = {
        auth: initialAuthState
    };

    const {container, getByLabelText, getByText} = render(<Root initialState={mockInitialState}/>);
    expect(container.firstChild).toMatchSnapshot();
    expect(getByLabelText(/Email Address.*/));
    expect(getByLabelText(/Password*/));
    expect(getByText('Sign in'));
});

Ziad 让我知道没有理由拥有act()它,这是为了解决create(). 既然没有使用代码,就create()不需要act().

结果,我的快照现在包含class而不是className因为class是实际 HTML DOM 中的内容,而className在 React 的“虚拟 DOM”中是等价的。

(之前)create()基于 React 的 Virtual DOM 的快照

className="MuiBox-root MuiBox-root-256"

(之后)render()基于 HTML DOM 的快照

class="MuiBox-root MuiBox-root-256"

如果您使用的是 Create React App,那么我会坚持使用 react-testing-library,因为它是随附的。

除了容器,您还可以使用asFragment进行快照测试。

 const {container} = render(<Root initialState={mockInitialState}/>);
 expect(asFragment).toMatchSnapshot();