Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-native-testing-library: how to test useEffect with act

I am using react-native-testing-library to test my react-native component. I have a component (for the purpose of this post, it has been over simplified):

export const ComponentUnderTest = () => {

 useEffect(() => {
   __make_api_call_here_then_update_state__
 }, [])

 return (
   <View>
     __content__goes__here
   </View>
 )
} 

Here is my (simplified) component.spec.tsx:

import { render, act } from 'react-native-testing-library';
import { ComponentUnderTest } from './componentundertest.tsx';

test('it updates content on successful call', () => {
   let root;
   act(() => {
      root = render(<ComponentUnderTest />); // this fails with below error message
   });    
   expect(...);
})

Now when I run this code, I get this error: Can't access .root on unmounted test renderer

enter image description here

I don't even now what this error message means. I followed the docs from the react-native-testing-library on how to test with act and useEffect.

Any help would be greatly appreciated. Thanks

like image 346
TheSoul Avatar asked Dec 01 '19 23:12

TheSoul


People also ask

How do you test the useEffect?

To test the component update useEffect hook you'd simply trigger state updates and check for effects in rendered elements. Redux hooks can be tested by mocking them and their implementation.

How do you test custom hooks react testing library?

1st case: unit testing simple custom hooks First, we need to create a test using describe. Then, we render a hook to use it for testing. Common way of doing it is to use the renderHook method from the React Hooks Testing Library. The next step is to figure out which cases we need to check.

How do you test a hook?

If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote. To reduce the boilerplate, we recommend using React Testing Library which is designed to encourage writing tests that use your components as the end users do.

How do you use hooks in react testing library?

The react-hooks-testing-library allows you to create a simple test harness for React hooks . It then runs them within the body of a function component. The library provides helpful utility functions for updating the inputs and retrieving your custom hook's outputs.


2 Answers

I found a workaround:

import { render, waitFor } from 'react-native-testing-library';
import { ComponentUnderTest } from './componentundertest.tsx';

test('it updates content on successful call', async () => {
   const root = await waitFor(() =>
       render(<ComponentUnderTest />);
   );   
   expect(...);
})
like image 136
Lucas Mathioni Avatar answered Oct 02 '22 18:10

Lucas Mathioni


You can do it using: @testing-library/react-native

Example:

import { cleanup, fireEvent, render, debug, act} from '@testing-library/react-native'

afterEach(() => cleanup());

test('given correct credentials, gets response token.', async () => {
    const { debug, getByPlaceholderText, getByRole } = await render(<Component/>);

    await act( async () => {
            const emailInput = getByPlaceholderText('Email');;
            const passwordInput = getByPlaceholderText('Password');
            const submitBtn = getByRole('button', {name: '/submitBtn/i'});

            fireEvent.changeText(emailInput, 'email');
            fireEvent.changeText(passwordInput, 'password');
            fireEvent.press(submitBtn);
    });
});

Should work with useEffect also but I haven't tested it out myself. Works fine with useState.

like image 36
Tony Avatar answered Oct 02 '22 18:10

Tony