Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing axios calls with Sinon, with redux and Karma

Hello in the redux documentation for testing they have have this example to test api calls:

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as actions from '../../actions/counter'
import * as types from '../../constants/ActionTypes'
import nock from 'nock'

const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)

describe('async actions', () => {
  afterEach(() => {
    nock.cleanAll()
  })

  it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', (done) => {
    nock('http://example.com/')
      .get('/todos')
      .reply(200, { body: { todos: ['do something'] }})

    const expectedActions = [
      { type: types.FETCH_TODOS_REQUEST },
      { type: types.FETCH_TODOS_SUCCESS, body: { todos: ['do something']  } }
    ]
    const store = mockStore({ todos: [] }, expectedActions, done)
    store.dispatch(actions.fetchTodos())
  })
})

I'm using karma test enviroment, and I think I can't use nock to test this. So I was looking into testing this using Sinon instead. Trouble is i don't understand how i would test using this as I'm not passing a callback into my api function call. I'm using axios to call my external API.

like image 648
Bobby Avatar asked Mar 01 '16 11:03

Bobby


2 Answers

I'm not an expert on async actions since in my app i test all these things separately (action creator, api calls with nock mocking a service, asynchronous behavior thanks to saga, however in the redux docs code looks like this

    const store = mockStore({ todos: [] })

    return store.dispatch(actions.fetchTodos())
      .then(() => { // return of async actions
        expect(store.getActions()).toEqual(expectedActions)
      })

So the dispatch returns your async action, and you have to pass test in the function that will be executed when your async action resolves. Nock'ing an endpoint should work just fine.

like image 195
MadNat Avatar answered Sep 28 '22 03:09

MadNat


For this you should use axios-mock-adapter

Example:

import MockAdapter from 'axios-mock-adapter';
import axios from 'axios';
import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import * as actionTypes from './userConstants';
import * as actions from './userActions';


const mockAxios = new MockAdapter(axios);
const mockStore = configureMockStore(middlewares);

describe('fetchCurrentUser', () => {
  afterEach(() => {
    mockAxios.reset();
  });

  context('when request succeeds', () => {
    it('dispatches FETCH_CURRENT_USER_SUCCESS', () => {
      mockAxios.onGet('/api/v1/user/current').reply(200, {});

      const expectedActions = [
        { type: actionTypes.SET_IS_FETCHING_CURRENT_USER },
        { type: actionTypes.FETCH_CURRENT_USER_SUCCESS, user: {} }
      ];

      const store = mockStore({ users: Map() });

      return store.dispatch(actions.fetchCurrentUser()).then(() =>
        expect(store.getActions()).to.eql(expectedActions)
      );
    });
  });
like image 22
Samo Avatar answered Sep 28 '22 02:09

Samo