Testing Lab 7: Action Tests
Objectives
- Mock the API
- Mock the Store
- Test Success and Failure
Steps
Mock the API
Create the directory
src\projects\__mocks__
.__mocks__
begins and ends with two underscores and is case-sensitiveCreate the file
src\projects\__mocks__\projectAPI.ts
to mock theprojectAPI
.Mock the
get
method.src\projects\__mocks__\projectAPI.ts
import { MOCK_PROJECTS } from '../MockProjects';
const projectAPI = {
get(page = 1, limit = 20) {
return Promise.resolve(MOCK_PROJECTS);
},
};
export { projectAPI };
Mock the Store
Open a
command prompt
(Windows) orterminal
(Mac).Change the current directory to
working\keeptrack
.Run one of the following sets of commands:
npm
npm install redux-mock-store @types/redux-mock-store --save-dev
Yarn
yarn add redux-mock-store @types/redux-mock-store --save-dev
Create the directory
src\projects\state\__tests__
.__tests__
begins and ends with two underscores and is case-sensitiveCreate the file
src\projects\state\__tests__\projectActions-test.ts
Add the test setup code including mocking the store away.
src\projects\state\__tests__\projectActions-test.ts
import configureMockStore from 'redux-mock-store';
import ReduxThunk from 'redux-thunk';
import { initialAppState } from '../../../state';
import { loadProjects } from '../projectActions';
import {
LOAD_PROJECTS_REQUEST,
LOAD_PROJECTS_SUCCESS,
LOAD_PROJECTS_FAILURE,
} from '../projectTypes';
import { projectAPI } from '../../projectAPI';
import { MOCK_PROJECTS } from '../../MockProjects';
jest.mock('../../projectAPI');
const middlewares = [ReduxThunk];
const mockStoreCreator = configureMockStore(middlewares);
describe('Project Actions', () => {
let store: any;
beforeEach(() => {
store = mockStoreCreator(initialAppState);
});
});
Note that the
jest.mock
replaces the actual implementation of theprojectAPI
with the mock we created in the last step. This is done by convention in Jest which replaces the implementation with the exported function or object in the__mocks__
directory.
At this point, you will receive the following error:
FAIL src/projects/state/__tests__/projectActions-test.ts
● Test suite failed to run
Your test suite must contain at least one test.
Test Success and Failure
- Attempt to test that the projects load successfully by adding the code.
src/projects/state/__tests__/projectActions-test.ts
import configureMockStore from 'redux-mock-store';
import ReduxThunk from 'redux-thunk';
import { initialAppState } from '../../../state';
import { loadProjects } from '../projectActions';
import {
LOAD_PROJECTS_REQUEST,
LOAD_PROJECTS_SUCCESS,
LOAD_PROJECTS_FAILURE
} from '../projectTypes';
import { projectAPI } from '../../projectAPI';
import { MOCK_PROJECTS } from '../../MockProjects';
jest.mock('../../projectAPI');
const middlewares = [ReduxThunk];
const mockStoreCreator = configureMockStore(middlewares);
describe('Project Actions', () => {
let store: any;
beforeEach(() => {
store = mockStoreCreator(initialAppState);
});
+ test('should load projects successfully', () => {
+ const expectedActions = [
+ { type: LOAD_PROJECTS_REQUEST },
+ {
+ type: LOAD_PROJECTS_SUCCESS,
+ payload: { projects: MOCK_PROJECTS, page: 1 }
+ }
+ ];
+
+ return store.dispatch(loadProjects(1)).then(() => {
+ const actions = store.getActions();
+ expect(actions).toEqual(expectedActions);
+ });
+ });
});
All tests including the
'should load projects successfully'
should pass.PASS src/projects/state/__tests__/projectActions-test.ts
Test that an error is returned when loading projects fails.
src/projects/state/__tests__/projectActions-test.ts
import configureMockStore from 'redux-mock-store';
import ReduxThunk from 'redux-thunk';
import { initialAppState } from '../../../state';
import { loadProjects } from '../projectActions';
import {
LOAD_PROJECTS_REQUEST,
LOAD_PROJECTS_SUCCESS,
LOAD_PROJECTS_FAILURE
} from '../projectTypes';
import { projectAPI } from '../../projectAPI';
import { MOCK_PROJECTS } from '../../MockProjects';
jest.mock('../../projectAPI');
const middlewares = [ReduxThunk];
const mockStoreCreator = configureMockStore(middlewares);
describe('Project Actions', () => {
let store: any;
beforeEach(() => {
store = mockStoreCreator(initialAppState);
});
...
+ test('should return error', () => {
+ projectAPI.get = jest
+ .fn(
+ // leave this commented initially
+ // projectAPI.get
+ )
+ .mockImplementationOnce(() => {
+ return Promise.reject('failed');
+ });
+
+ const expectedActions = [
+ { type: LOAD_PROJECTS_REQUEST },
+ {
+ type: LOAD_PROJECTS_FAILURE,
+ payload: 'failed'
+ }
+ ];
+
+ return store.dispatch(loadProjects(1)).then(() => {
+ const actions = store.getActions();
+ expect(actions).toEqual(expectedActions);
+ });
+ });
});
The new test should pass.
PASS src/projects/state/__tests__/projectActions-test.ts