Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-test-renderer's create() vs. @testing-library/react's render()

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?

like image 377
Michael Osofsky Avatar asked Nov 01 '19 03:11

Michael Osofsky


People also ask

Does React testing library use React test renderer?

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.

What does render () mean in React?

React renders HTML to the web page by using a function called render(). The purpose of the function is to display the specified HTML code inside the specified HTML element. In the render() method, we can read props and state and return our JSX code to the root component of our app.

What is the best testing library for React?

Jest. Jest was the most popular JavaScript unit testing framework in 2020. For web apps that are based on React, Jest is the preferred framework. Apart from React, Jest supports unit testing of Angular, VueJS, NodeJS, and others.

What is the difference between React testing library and Jest?

Jest provides a great iteration speed combined with powerful features like mocking modules and timers so you can have more control over how the code executes. React Testing Library is a set of helpers that let you test React components without relying on their implementation details.


Video Answer


1 Answers

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"
like image 189
Michael Osofsky Avatar answered Sep 18 '22 12:09

Michael Osofsky