4

I can't get a basic test working with react-test-utils and Redux as shown below.

import React from 'react'
import { Provider } from 'react-redux'
import { combineReducers } from 'redux'
import { configureStore } from '@reduxjs/toolkit'
import { render } from '@testing-library/react'

it('renders welcome message', () => {
    const store = configureStore({
        reducer: combineReducers({}),
    })

    console.log(store)

    const { getByText } = render(
        <Provider store={store}>
            <h1>hi</h1>
        </Provider>
    )
    expect(getByText('hi')).toBeInTheDocument()
})

it fails with this error

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

      14 |      console.log(store)
      15 | 
    > 16 |      const { getByText } = render(
         |                            ^
      17 |              <Provider store={store}>
      18 |                      <h1>hi</h1>
      19 |              </Provider>

      at reconcileChildFibers (node_modules/react-dom/cjs/react-dom.development.js:14348:23)
      at reconcileChildren (node_modules/react-dom/cjs/react-dom.development.js:16762:28)
      at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17542:5)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:18596:16)
      at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:188:14)
...

But if comment out the <Provider> like shown below then test passes

it('renders welcome message', () => {
    const store = configureStore({
        reducer: combineReducers({}),
    })

    console.log(store)

    const { getByText } = render(
        // <Provider store={store}>
            <h1>hi</h1>
        // </Provider>
    )
    expect(getByText('hi')).toBeInTheDocument()
})
4
  • Can you provide a codesandbox link with the same test? Commented Apr 24, 2020 at 17:01
  • @MukeshSoni I can't seem to get it reproducible in code sandbox. This is a boilerplate repo. Can I share this in a branch? It's pretty easy to run the code. Commented Apr 24, 2020 at 21:55
  • You could consider mocking your store using github.com/reduxjs/redux-mock-store. You could provide only needed pieces of your store considering the component under test. Works great. Commented May 7, 2020 at 19:19
  • Thanks @Flo but I don't want to mock the store. Commented May 9, 2020 at 13:14

2 Answers 2

2

You can specify Provider as a wrapper to render method from react-testing library

it('renders welcome message', () => {
    const store = configureStore({
        reducer: combineReducers({}),
    })

    console.log(store)
    const Wrapper = ({children}) => {
         return <Provider store={store}>{children}</Provider>
    }
    const { getByText } = render(
         <h1>hi</h1>, 
         {wrapper: Wrapper}
    )
    expect(getByText('hi')).toBeInTheDocument()
})

You could also overrider the testing-library's render method to make the Wrapper logic Generic as mentioned in the documentation

// test-utils.js
import React from 'react'
import { render as rtlRender } from '@testing-library/react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { initialState as reducerInitialState, reducer } from './reducer'

function render(
  ui,
  {
    initialState = reducerInitialState,
    store = createStore(reducer, initialState),
    ...renderOptions
  } = {}
) {
  function Wrapper({ children }) {
    return <Provider store={store}>{children}</Provider>
  }
  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions })
}

// re-export everything
export * from '@testing-library/react'

// override render method
export { render }

and use it like

// counter.test.js
import React from 'react'
import { createStore } from 'redux'
// We're using our own custom render function and not RTL's render
// our custom utils also re-export everything from RTL
// so we can import fireEvent and screen here as well
import { render, fireEvent, screen } from './test-utils'
import '@testing-library/jest-dom/extend-expect'

it('renders welcome message', () => {
    const store = configureStore({
        reducer: combineReducers({}),
    })

    const { getByText } = render(
            <h1>hi</h1>,
         {store}
    )
    expect(getByText('hi')).toBeInTheDocument()
})
Sign up to request clarification or add additional context in comments.

2 Comments

Please let me know if the above solution solves your problem or not
This gives the same error. Thanks for helping but it looks like your suggestion is just wrapping things differently.
0

You may consider check the following dependencies in place, sometimes you need to uninstall and install as development, like react-dom case.

yarn add react-dom  // or npm i react-dom
yarn add redux
yarn add react-test-renderer
yarn remove react-dom
yarn add react-dom -D
yarn remove react-redux
yarn add react-redux
yarn add @reduxjs/toolkit

Your code runs on my machine without no issues

enter image description here

@Ryan as per your request here is the test.test.js code:

import React from 'react'
import { Provider } from 'react-redux'
import { combineReducers, createStore } from 'redux'
import { configureStore } from '@reduxjs/toolkit'
import { render } from '@testing-library/react'

it('renders welcome message', () => {
    const store = configureStore({
        reducer: combineReducers({}),
    })

    console.log(store)

    const { getByText } = render(
        <Provider store={store}>
            <h1>hi</h1>
        </Provider>
    )
    expect(getByText('hi')).toBeInTheDocument()
})

1 Comment

Thanks @Feras i tried reinstalling those packages and it still didn't work on my box. Can you post the code for the test you ran? I don't see a test.test.js file? I don't see that in the repo

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.