问题
I'm new to React and confused about all the testing libraries. I got my test code to work but it seems redundant to have to call create()
from react-test-renderer in order to use its toMatchSnapshot()
and have to call render()
from @testing-library/react in order to use its assertions such as 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'));
});
As a newbie, it's hard for me to understand the difference between all these React libraries. But I'm thinking there must be a simpler way.
How can I simplify my test code so I only have to call one thing that renders the component so that I can do snapshot testing and more specific assertions?
回答1:
I got the answer from Ziad Saab at Codementor.io:
create()
allows you test against the virtual DOM (i.e. the "React DOM")render()
comes from react testing library and renders your tree but also allows you to have all the get*() assertions. It allows you to test against the DOM.
Here's how the code can be simplified:
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 let me know that there was no reason to have act()
, it was something to work around a bug in create()
. Now that the code doesn't used create()
there is no need for act()
.
As a result, my snapshot now contains class
instead of className
because class
is what's in the actual HTML DOM whereas className
is its equivalent in React's "Virtual DOM".
(Before) Snapshot with create()
based on React's Virtual DOM:
className="MuiBox-root MuiBox-root-256"
(After) Snapshot with render()
based on HTML DOM:
class="MuiBox-root MuiBox-root-256"
来源:https://stackoverflow.com/questions/58653872/react-test-renderers-create-vs-testing-library-reacts-render