18

我是 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 库之间的区别。但我认为必须有一个更简单的方法。

我怎样才能简化我的测试代码,所以我只需要调用一个渲染组件的东西,以便我可以进行快照测试和更具体的断言?

4

2 回答 2

11

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

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

  • render()来自反应测试库并呈现您的树,但也允许您拥有所有 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"
于 2019-11-01T19:33:41.103 回答
2

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

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

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

于 2021-07-27T05:43:12.607 回答