4

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');
});

4
  • After the render line just do expect(screen.getByText(firstName)).toBeInTheDocument() (same for surname) and remove the const declarations Commented Aug 15, 2022 at 15:58
  • thanks Tom. something still seems slightly a miss but that looks closer, so I've updated the snippet in the OP. thanks! Commented Aug 15, 2022 at 16:14
  • Are you asking how to do snapshot testing with react testing library? "seems slightly a miss" and "it's not quite right" aren't things we can help you with. What are you trying to accomplish specifically? Commented Aug 15, 2022 at 16:20
  • Hi Andy. What I'm trying to do is migrate the above test (using Enzyme) to RTL. Happy to still use Jest for snapshot purposes. Commented Aug 15, 2022 at 16:25

2 Answers 2

2

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();
});
Sign up to request clarification or add additional context in comments.

Comments

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);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.