redux saga is returning SagaTestError: put expectation unmet when checking api call

3.4k Views Asked by At

I'm testing a simple redux saga function using redux test plan, the get posts test is returning a failure

SagaTestError: 
put expectation unmet:

Expected
--------
{ '@@redux-saga/IO': true,
  combinator: false,
  type: 'PUT',
  payload: { channel: undefined, action: { type: 'GET_POSTS_INIT' } } }

I'm testing to check if the posts array is empty being that the server is not running, is this the right approach to testing this function ?

post saga test

it(" fetchs post failure ", () => { // passes
    const error = new Error("Whoops");
    return expectSaga(getPosts)
        .provide([[call(api.post.getPosts), throwError(error)]])
        .put({ type: types.GET_POSTS_FAILURE, error: error })
        .run();
});

it("should test fetches posts", () => { // this test doesn't pass
    const posts = { posts: [] }; // is this the right approach ?
    return expectSaga(watchPosts)
        .provide([[call(api.post.getPosts), posts]])
        .put({ type: types.GET_POSTS_INIT })
        .dispatch({ type: types.GET_POSTS_SUCCESS, payload: posts })
        .silentRun();
});

post saga

export function* getPosts() {
    try {
        const posts = yield call(api.post.getPosts); // call api from axios express back end
        yield put(actionTypes.getPostsSuccess(posts));
    } catch (error) {
        yield put(actionTypes.getPostsFailure(error));
    }
}

export function* watchPosts() {
    yield takeLatest(types.GET_POSTS_INIT, getPosts);
}
1

There are 1 best solutions below

0
Lin Du On BEST ANSWER

You need to dispatch types.GET_POSTS_INIT action to watchPosts saga and put types.GET_POSTS_SUCCESS action with payload posts.

E.g.

index.ts:

import { call, takeLatest, put } from 'redux-saga/effects';
import { api } from './api';
import { types } from './types';

const actionTypes = {
  getPostsSuccess(posts) {
    return { type: types.GET_POSTS_SUCCESS, payload: { posts } };
  },
  getPostsFailure(error) {
    return { type: types.GET_POSTS_FAILURE, error };
  },
};

export function* getPosts() {
  try {
    const posts = yield call(api.post.getPosts);
    yield put(actionTypes.getPostsSuccess(posts));
  } catch (error) {
    yield put(actionTypes.getPostsFailure(error));
  }
}

export function* watchPosts() {
  yield takeLatest(types.GET_POSTS_INIT, getPosts);
}

api.ts:

export const api = {
  post: {
    async getPosts() {
      return 'mocked posts';
    },
  },
};

types.ts:

export const types = {
  GET_POSTS_INIT: 'GET_POSTS_INIT',
  GET_POSTS_FAILURE: 'GET_POSTS_FAILURE',
  GET_POSTS_SUCCESS: 'GET_POSTS_SUCCESS',
};

index.test.ts:

import { getPosts, watchPosts } from './';
import { api } from './api';
import { types } from './types';
import { expectSaga } from 'redux-saga-test-plan';
import { throwError } from 'redux-saga-test-plan/providers';
import { call } from 'redux-saga/effects';

describe('62105055', () => {
  it(' fetchs post failure ', () => {
    const error = new Error('Whoops');
    return expectSaga(getPosts)
      .provide([[call(api.post.getPosts), throwError(error)]])
      .put({ type: types.GET_POSTS_FAILURE, error: error })
      .run();
  });

  it('should test fetches posts', () => {
    const posts = { posts: [] };
    return expectSaga(watchPosts)
      .provide([[call(api.post.getPosts), posts]])
      .put({ type: types.GET_POSTS_SUCCESS, payload: { posts } })
      .dispatch({ type: types.GET_POSTS_INIT })
      .silentRun();
  });
});

unit test result with coverage report:

 PASS  src/stackoverflow/62105055/index.test.ts
  62105055
    ✓  fetchs post failure  (11 ms)
    ✓ should test fetches posts (252 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   93.75 |      100 |      80 |   93.33 |                   
 api.ts   |      50 |      100 |       0 |      50 | 4                 
 index.ts |     100 |      100 |     100 |     100 |                   
 types.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.166 s

package versions:

"redux-saga": "^1.1.3",
"redux-saga-test-plan": "^4.0.0-rc.3",
"typescript": "^3.9.7",
"jest": "^26.1.0",