testing-library / react-testing-library

🐐 Simple and complete React DOM testing utilities that encourage good testing practices.
https://testing-library.com/react
MIT License
18.99k stars 1.1k forks source link

jest+react-redux+RTL: "Provider(...): Nothing was returned from render" #989

Closed csvan closed 2 years ago

csvan commented 2 years ago

Relevant code or config:

import '@testing-library/jest-dom';

import React from 'react';
import { render, screen } from '@testing-library/react';
const { Provider } = require('react-redux');
const { createStore } = require('redux');

describe('HelloHeading', () => {
  it('shows the correct text', () => {
    const store = createStore((innerState) => innerState, {});
    function Wrapper({ children }) {
      return <Provider store={store}>{children}</Provider>;
    }
    render(<div data-testid="my-tag">hello there</div>, { wrapper: Wrapper });
    expect(screen.getByTestId('my-tag')).toHaveTextContent('hello there');
  });
});

What you did:

Run the above test case with a vanilla Jest config

What happened:

Test fails with

Error: Uncaught [Error: Provider(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.]

Reproduction:

Run the above test case using Jest and RTL

Problem description:

I am essentially using the same approach as outlined at https://redux.js.org/usage/writing-tests#reducers in order to use RTL to test React apps using Redux. However, even in a trivial case like this one, I keep getting the above error - something seems to fail while rendering the Redux provider, but it is unclear what.

I have tested the same code using Enzyme + Jest, and it works fine. Other providers, such as those used by react-intl and react-router work without issue. I understand this might be an issue specific to react-redux, but I wanted to start here.

Suggested solution:

It should just work as indicated. I am not sure what needs fixing at this stage.

eps1lon commented 2 years ago

Thanks for the report.

Could you compile this into a cloneable repository so that it's easier to reproduce for us? Thanks.

MatanBobi commented 2 years ago

This is working for me with your exact code and a fresh CRA (the only difference is jest 26) so please attach a reproducible example. image

mohsenireza commented 2 years ago

This happens when you mock 'react-redux'

If you mocked 'react-redux' for unit testing but you want to use the actual module for integration testing, make sure to unmock the module by adding this code at the top of your integration test files:

jest.unmock('react-redux')

RLiriaVA commented 2 years ago

Hi Can you xplaing beter please ?

El El mar, mar. 15, 2022 a la(s) 10:51 a. m., Reza Mohseni < @.***> escribió:

This happens when you mock 'react-redux'

If you mocked 'react-redux' for unit testing but you want to use the actual module for integration testing, make sure to unmock the module by adding this code at top of your integration test files:

jest.unmock('react-redux')

— Reply to this email directly, view it on GitHub https://github.com/testing-library/react-testing-library/issues/989#issuecomment-1068076545, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWS5U2YSYUOACX7YYM3JSDLVACPVNANCNFSM5G6MKYNA . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>

mohsenireza commented 2 years ago

@RLiriaVA You can consider a React component as a kind of function that returns some HTML elements. so based on what I said, in the simplest way, you can consider <Provider /> component something like this:

function Provider({children}) {
    return children;
}

which the children is what goes between starting and closing tag of <Provider />

And now look at the error that says:

Error: Uncaught [Error: Provider(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.]

which means the Provider function returns nothing, or in other words, it doesn't have any return statement anymore!!!

It means we changed the Provider function somewhere in our code. either by hand or by mocking!

One of the common mistakes that happens is you mocked the react-redux module somewhere in your code because you didn't want the default functionality of something that is exported from it and you are still using the mocked version.

Please notice that if you use Manual Mocks for react-redux and put the mock inside __mocks__/react-redux.js, it will be applied globally and the mocked version will be used in every test file unless you unmock it in specific files which I will explain how to unmock a module later.

By default many functions are exported from react-redux module, like Provider and connect. and when you mock react-redux module, jest by default changes the implementation of all of them to jest.fn() which is a mocked empty function that doesn't have any return statement and it means it returns nothing!!!

So after mocking the react-redux module, the Provider inside it, is something (of course not exactly!!!) like this:

{
    Provider: () => {}
}

that is why the error says Nothing was returned

Now what should I do ?! You have two ways:

Of course this is one the possible scenarios, I hope this solves your problem.

csvan commented 2 years ago

Forgot about this issue, the problem was, as @mohsenireza indicated, that I had mocked out react-redux. I did not notice this because the mock was located in my __mocks__ folder and written by another team member, so I looked in all the wrong places.

RLiriaVA commented 2 years ago

Hi everyone from Dominican Republic...!!

How People can plan they projects and start learn about c++ from beginning to the end Whit inclusive corrects orientations Guys.?

ryan-postoffice commented 2 years ago

This happens when you mock 'react-redux'

If you mocked 'react-redux' for unit testing but you want to use the actual module for integration testing, make sure to unmock the module by adding this code at the top of your integration test files:

jest.unmock('react-redux')

This was exactly my issue. Thanks for the suggestion! :)