1

My specs are behaving weirdly in that when I run the tests alone, they pass. However, when I run the test suite all together, the failure tests still continue to use the success axios mock instead of using the correct failing http axios mock. This results in my tests failing. Am I missing something for isolating the 2 mocks from each other in the different portions of code?

jobactions.js

export const loadUnassignedJobs = (job_type) => {
  if (!['unscheduled', 'overdue'].includes(job_type)) {
    throw 'Job Type must be "unscheduled" or "overdue".';
  }
  return (dispatch) => {
    dispatch({type: JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED, job_type });
    return axios.get(defaults.baseapi_uri + 'jobs/' + job_type)
      .then(function (response) {
        dispatch(updateUnassignedJobs(response.data.jobs));
        // handle success
      })
      .catch(function (error) {
        // handle error
        dispatch({ type: JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE, error });
      })
      .then(function () {
        // always executed
      });
  }
};

export const updateUnassignedJobs = (unassigned_jobs) => {
  let unassigned_job_ids = [];
  let jobs = {};
  for (let job of unassigned_jobs) {
    unassigned_job_ids.push(job.id);
    jobs[job.id]=job;
  }

  return({
    type: JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS,
    jobs,
    unassigned_job_ids,
  });
};

spec.js

import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import * as jobActions from "../../../app/javascript/actions/JobActions"
import { findAction } from '../support/redux_store'
import * as JobActionTypes from '../../../app/javascript/constants/JobActionTypes'
import fixtures_jobs_unscheduled_success from '../fixtures/jobs_unscheduled_success'
import moxios from "moxios";

export const mockStore = configureMockStore([thunk]);

let store;

describe ('loadUnassignedJobs', () => {
  context('when bad parameters are passed', async () => {
    it('will raise an error', () => {
      const store = mockStore();

      expect(() => {
        store.dispatch(jobActions.loadUnassignedJobs('wrong_type'));
      }).to.throw('Job Type must be "unscheduled" or "overdue".');
    });
  });

  context('when unscheduled is passed', () => {
    beforeEach(() => {
      moxios.install();
      console.log("before each called");
      console.log(moxios.requests);
      store = mockStore();
      store.clearActions();
    });

    afterEach(() => {
      console.log("after each called");
      console.log(moxios.requests);
      moxios.uninstall();
    });
    context('on success', () => {
      beforeEach(() => {
        moxios.wait(() => {
          let request = moxios.requests.mostRecent();
          request.respondWith({
            status: 200,
            response: fixtures_jobs_unscheduled_success
          });
        });
      })
      it('dispatches LOAD_UNASSIGNED_JOBS_STARTED', () => {
        store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
          expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED)).to.be.eql({
            type: JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED,
            job_type: 'unscheduled'
          });
        });
      });

      it('dispatches updateUnassignedJobs()', () => {
        store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
          expect(findAction(store,JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS)).to.be.eql(jobActions.updateUnassignedJobs(fixtures_jobs_unscheduled_success.jobs))
        });
      });
    });

    context('on error', () => {
      beforeEach(() => {
        //console.log("before each on error called");
        //console.log(moxios.requests);

        moxios.wait(() => {
          console.log('after waiting for moxios..')
          console.log(moxios.requests);
          let request = moxios.requests.mostRecent();
          request.respondWith({
            status: 500,
            response: { error: 'internal server error' }
          });
        });
      })
      it('dispatches LOAD_UNASSIGNED_JOBS_FAILURE', (done) => {
        console.log(moxios.requests);
        store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
          console.log(moxios.requests);
          console.log(store.getActions());
          expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE)).to.include({
            type: JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE
          });
          expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE).error).to.include({
            message: 'Request failed with status code 500'
          });
          done();
        });
      });
      it('does not dispatch LOAD_UNASSIGNED_JOBS_SUCCESS', (done) => {
        store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
          expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS)).to.be.undefined;
          done();
        });
      });
    })
  });
});

describe('updateUnassignedJobs', () => {
  it('assigns jobs to hash and creates an unassigned_job_ids array', () => {
    expect(jobActions.updateUnassignedJobs([ { id: 1, step_status: 'all_complete' }, { id: 2, step_status: 'not_started' } ])).to.be.eql(
      {
        type: JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS,
        jobs: { 1: { id: 1, step_status: 'all_complete' }, 2: { id: 2, step_status: 'not_started' } },
        unassigned_job_ids: [ 1,2 ]
      }
    )
  });
});
PressingOnAlways
  • 11,948
  • 6
  • 32
  • 59

1 Answers1

1

Found the issue!

The it() blocks for the success case were not using the done callback causing the afterEach() moxios.uninstall() to be called prematurely and not resetting the requests after the call was complete. Fixing this, and now all the tests pass.

PressingOnAlways
  • 11,948
  • 6
  • 32
  • 59
  • Pointed me in the right direction. My situation was slightly unique though, I was calling `done` after the promise from an async method resolves. Since all my assertions were within the `moxios.wait` I just moved this call to the `then` block like the docs suggest. – karuhanga Apr 29 '19 at 08:17