react-reducer-provider.github.io

Asynchronous/Synchronous React Centralized State

Follow me on GitHub

Testing

Unit Test - Mocking Reducer Providers hooks

  • Useful when testing custom hooks.
  • Useful when using enzyme shallow.
    • No need for SyncReducerProvider nor AsyncReducerProvider.

Mocking useReducer:

  • With traditional & sensational Jasmine:
  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  const mockState = {}
  const mockDispatcher = jasmine.createSpy()
  spyOn(ReducerProviderModule, 'useReducer')
    .and
    .returnValue([
      mockState,
      mockDispatcher
    ])

or

if values is going to change from test case to test case:

  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  let mockState
  let mockDispatcher
  spyOn(ReducerProviderModule, 'useReducer')
    .and
    .callFake(() => [
      mockState,
      mockDispatcher
    ])
  • With Jest:
  const mockState = {}
  const mockDispatcher = jest.fn()
  jest.mock('react-reducer-provider', () => ({
    useReducer: () => ([
      mockState,
      mockDispatcher
    ])
  }))

Mocking useReducerState:

  • With traditional & sensational Jasmine:
  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  const mockState = {}
  spyOn(NamedReducerModule, 'useReducerState')
    .and
    .returnValue(mockState)

or

if state is going to change from test case to test case:

  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  let mockState
  spyOn(ReducerProviderModule, 'useReducerState')
    .and
    .callFake(() => mockState)
  • With Jest:
  const mockState = {}
  jest.mock('react-reducer-provider', () => ({
    useReducerState: () => mockState
  }))

Mocking useReducerDispatcher:

  • With traditional & sensational Jasmine:
  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  const mockDispatcher = jasmine.createSpy()
  spyOn(ReducerProviderModule, 'useReducerDispatcher')
    .and
    .returnValue(mockDispatcher)

or

if dispatcher is going to change from test case to test case:

  import * as ReducerProviderModule from 'react-reducer-provider'
  ..
  let mockDispatcher
  spyOn(ReducerProviderModule, 'useReducerDispatcher')
    .and
    .callFake(() => mockDispatcher)
  • With Jest:
  const mockDispatcher = jest.fn()
  jest.mock('react-reducer-provider', () => ({
    useReducerDispatcher: () => mockDispatcher
  }))

Examples can be seen at: MockingReducerProvider.test.jsx.

Integration Test - Testing how a component that requires to be enclosed in a Reducer Provider behave

1 . Use enzyme mount.
2 . Enclosed component with a SyncReducerProvider or AsyncReducerProvider:

  • add the required properties:
    • id: identifier of the context used by the component to be test.
    • initialState: the state required by the test.
    • reducer: the reducer required by the test.
  it('test description', () => {
    const component = mount(
      <SyncReducerProvider
        id='theContextName'
        initialState=
        reducer={(prevState, action) => {
          switch (action) {
            case 'ACTION1':
              return {
                field1: valueA,
                fieldN: valueB,
              }
            default:
              return prevState
          }
        }}
      >
        <ComponentToBeTest />
      </SyncReducerProvider>
    )

Examples can be seen at: SingletonReducerProvider.test.jsx, SyncReducerProvider.test.jsx and AsyncReducerProviderWithAsync.test.jsx.

Asynchronous testing

When a Component make an asynchronous call to the reducer (or some React hook) inside an useEffect then use act for testing, e.g.

import { useReducer } from 'react-reducer-provider'

export function SomeComponent() {
  const [ state, dispatch ] = useReducer()
  React.useEffect(() => {
    asyncCall().then(() => dispatch('Some'))
  }, [])
  ..
import { act } from 'react-dom/test-utils'

it('should render SomeComponent', async () => {
  await act(async () => {
    const main = mount(
      <AsyncReducerProvider reducer={() => {/*..*/} } initialState={someValue}>
          <SomeComponent/>
      </AsyncReducerProvider>
    )
    expect(main.contains(/* .. */)).toBe(true)
  })
})

Main documentation

Back to homepage