Testing React & Redux app w templates using Enzyme, Mocha and Expect
import expect from 'expect';
import {createStore} from 'redux';
import rootReducer from '../reducers';
import intitialState from '../reducers/initialState';
import * as fooActions from '../actions/fooActions';
describe('Store integration test', () => {
it('should handle the action', () => {
//arrange
const store = createStore(rootReducer, initialState);
const foo = { bar: "a" };
//act
const action = fooActions.createFooSuccess(foo);
store.dispatch(action);
//assert
const actual = store.getState().foo;
expect(actual).toEqual(foo);
});
});
// JS, React, Redux ES6, Testing, Enzyme, Mocha, Template
import expect from 'expect';
import React from 'react';
import {mount, shallow} from 'enzyme';
import SampleConnectedComponentForm from './SampleConnectedComponentForm';
describe('Testing connected components', () => {
it('sets error message when trying to save empty title', ()=>{
// There are two ways to render connected components:
// 1. Wrap the component with Provider:
// const wrapper = mount(<Provider store={store}><SampleConnectedComponentForm/></Provider>);
// 2. Exporting connected component itself besides exporting connected wrap.
// simply add export near class definition, there should be two exports for one class, assume we have that:
// Mock mapStateToProps and mapDispatchToProps
const props = {
arrPropFromStore: [],
objPropFromStore : {},
actions: {
methodToDispatch: () => { return Promise.resolve(); }
}
};
const wrapper = mount(<SampleConnectedComponentForm {...props}/>);
const saveButton = wrapper.find('input').last();
expect(saveButton.prop('type').toBe('submit'));
saveButton.simulate('click');
expect(wrapper.state().errors.title).toBe('Title is empty.');
});
});
// JS, React, ES6, Testing, Enzyme, Mocha, Template
import expect from 'expect';
import React from 'react';
import {mount, shallow} from 'enzyme';
import SampleForm from './SampleForm';
function setup(boolProp){
const props = {
objProp: {}, boolProp: boolProp,
funcProp: () => {}
};
return shallow(<SampleForm {...props}/>);
}
describe('Testing via Enzyme', ()=> {
it('renders form and h1', ()=>{
const wrapper = setup(false);
expect(wrapper.find('form').length).toBe(1);
expect(wrapper.find('h1').text()).toEqual('The Title');
});
it('save button is labeled "Save" when boolProp is false', ()=>{
const wrapper = setup(false);
expect(wrapper.find('input').props().value).toBe('Save');
});
it('save button is labeled "Saving..." when boolProp is true', ()=> {
const wrapper = setup(true);
expect(wrapper.find('input').props().value).toBe('Saving...');
});
});
They don't depend any other class, pretty straightforward.
Mock two things: Store and HTTP Calls. Store --> redux-mock-store HTTP Calls --> nock
import expect from 'expect';
import * as fooActions from './fooActions';
import thunk from 'redux-thunk';
import nock from 'nock';
import configureMockStore from 'redux-mock-store';
import types from './actionTypes';
const middleware = [thunk];
const mockStore = configureMockStore(middleware);
describe('Async actions', () => {
afterEach(() => {
nock.cleanAll();
});
it('should create SAMPLE_ACTION when loading result from another server', (done) => {
nock('http://example.com/')
.get('/sample')
.reply(200, {body: { foo: {[{bar: "a"}], "bar" : 3 }}});
const expectedAction = {type: types.SAMPLE_ACTION, body: { foo: {[{bar: "a"}], "bar" : 3 }}};
const store = mockStore({foo: {}}, expectedAction);
store.dispatch(fooActions.fooThunk()).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(types.SAMPLE_ACTION);
done(); // tells mocha that async work is complete.
});
});
});
Disclaimer: Not a solution to check if that method is called in mapStateToProps