Reputation: 1084
I've recently inherited a codebase with a requirement to use RTL (currently using Enzyme). A lot of the Enzyme tests are fairly simple like so and pass with no issues:
const render = ({ firstName, surname } = {}) => {
const props = { firstName, surname };
return shallow(<MyComponent {...props} />);
};
test('renders firstName and surname', () => {
expect(
render({
firstName: 'My first name',
surname: 'My surname',
})
).toMatchSnapshot();
});
I'm having issues however migrating this test to React Testing Library - I have the below as a very rough starting point, but know that it's not quite right. Can anyone suggest helpful docs for basics like this or suggest any code improvements? TIA
test('renders firstName and surname', () => {
props = { firstName, surname };
render(<MyComponent {...props} />);
expect(screen.getByText(props.firstName)).toBe('My first name');
expect(screen.getByText(props.surname)).toBe('My surname');
});
Upvotes: 3
Views: 1220
Reputation: 1
Here's the modified code with explanation:
test('renders firstName and surname', () => {
props = { firstName, surname };
const {asFragment} = render(<MyComponent {...props} />);
// You might need to update snapshot
// The observed diff should be DocumentFragment created by RTL
expect(asFragment()).toMatchSnapshot();
// Additionally, you can also assert the prop values
expect(screen.getByText(props.firstName)).not.toBe(null);
expect(screen.getByText(props.surname)).not.toBe(null);
});
Upvotes: 0
Reputation: 1407
As someone who also had to work with both I learned that RTL is very different conceptionally to enzyme. RTL discourages making prop assertions, instead they recommend writing tests that are user driven. So my main improvement suggestion would be to think and ask youself before you write a test "what does the user see now?" or "what changed on the screen for the user?".
In the test above you are basically checking that the props are what you defined them to be which is how things are done in enzyme but when you stop to think about it, it's quite redundant.
I fully understand that some components are quite simple and don't have much to test in them so in that case, I would re-write your tests in the following way to be more aligned with the ethos of RTL which in this case is something along the lines of "does the user see what I expect them to see?". Also I recommend putting your element queries into variables for better readability.
it('renders firstName and surname', () => {
const props = {
firstName: 'My first name',
surname: 'My surname',
};
render(<MyComponent {...props} />);
const firstName = screen.getByText(props.firstName);
const surname = screen.getByText(props.surname);
expect(firstName).toBeInTheDocument();
expect(surname).toBeInTheDocument();
});
Upvotes: 2