Testing
Unit Test - Mocking Reducer Providers hooks
- Useful when testing custom hooks.
- Useful when using enzyme
shallow
.- No need for
SyncReducerProvider
norAsyncReducerProvider
.
- No need for
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)
})
})