The onSuccess
and onFailed
methods have different references in saga and test cases. The assertions will definitely fail.
Since you declared these two methods inside saga, we were unable to import them into our test cases through module requiring. So, we are unable to use the same references of these two methods in our test case.
We can use inspect general assertion provided by redux-saga-test-plan
.
If your saga yields a nondeterministic type of value or something not easily covered by the effect assertions or other general assertions, then you can use inspect
to retrieve the actual yielded value and perform your own assertions with your favorite assertion library.
We use it to get the returned effect of yield put(actions.bar({...}))
. Then, we can get the redux action created by actions.bar({...})
in test case include onSuccess
, onFailed
methods, and everything you passed in actions.bar()
action creator in the foo
saga.
We can assert these two methods using expect.any(Function)
provided by jestjs. You can even execute and test them.
E.g.
saga.ts
:
import { put } from 'redux-saga/effects';
import * as actions from './actions';
export function* foo() {
yield put(actions.start());
yield put(
actions.bar({
onSuccess: () => {
// do something
},
onFailed: () => {
// do something else
},
}),
);
yield put(actions.done());
}
saga.test.ts
:
import { testSaga } from 'redux-saga-test-plan';
import { foo } from './saga';
import * as actions from './actions';
import { PutEffect } from 'redux-saga/effects';
import { AnyAction } from 'redux';
describe('54885611', () => {
it('should pass', () => {
const logSpy = jest.spyOn(console, 'log');
testSaga(foo)
.next()
.put(actions.start())
.next()
.inspect<PutEffect<AnyAction>>((yieldedValue) => {
expect(yieldedValue.payload.action).toEqual({
type: 'START',
payload: expect.objectContaining({ onSuccess: expect.any(Function), onFailed: expect.any(Function) }),
});
// test onSuccess
yieldedValue.payload.action.payload.onSuccess();
expect(logSpy).toBeCalledWith('do something');
// test onFailed
yieldedValue.payload.action.payload.onFailed();
expect(logSpy).toBeCalledWith('do something else');
logSpy.mockRestore();
})
.next()
.put(actions.done())
.next()
.isDone();
});
});
unit test result:
PASS src/stackoverflow/54885611/saga.test.ts
54885611
✓ should pass (25 ms)
console.log
do something
at console.<anonymous> (node_modules/jest-mock/build/index.js:848:25)
console.log
do something else
at console.<anonymous> (node_modules/jest-mock/build/index.js:848:25)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
actions.ts | 100 | 100 | 100 | 100 |
saga.ts | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.351 s