I've read the Async Action Testing section on the redux doc page. But I am having a hard time wrapping my head around testing these actions. This is my action: forgot-password.
function requestAddPasswordResetRequest(){
return {
type: REQUEST_ADD_PASSWORD_RESET_REQUEST
};
}
function requestAddPasswordResetRequestSuccess(){
return {
type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS
};
}
function requestAddPasswordResetRequestFailure(error){
return {
type: REQUEST_ADD_PASSWORD_RESET_REQUEST_FAILURE,
payload: error,
error:true
};
}
export default function addPasswordResetRequest(email){
return dispatch => {
dispatch(requestAddPasswordResetRequest(email));
return addPasswordResetRequestAPI(email)
.then(() =>{
dispatch(requestAddPasswordResetRequestSuccess());
})
.catch((error) => {
dispatch(requestAddPasswordResetRequestFailure(error));
});
};
}
this is the function: addPasswordResetRequestAPI(email):
export const addPasswordResetRequest = (email) => {
return fetch(
NC_SETTINGS.API_ROOT + '/password-reset-requests',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: email,
code: NC_SETTINGS.GROUP.code
})
}
)
.then(handleResponse);
};
handleResponse, just returns a response to see if the email is valid or not.
Here is my test page:
/* globals global, describe, it */
"use strict";
import forOwn from 'lodash/object/forOwn';
import { assert, expect, should } from 'chai';
import { spy } from 'sinon';
import { applyMiddleware } from 'redux';
//import fetch from 'isomorphic-fetch';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import {
REQUEST_ADD_PASSWORD_RESET_REQUEST,
REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS,
REQUEST_ADD_PASSWORD_RESET_REQUEST_FAILURE
} from 'actions/types';
import nock from 'nock';
const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);
import Actions from 'actions';
describe('forgot password async actions', () => {
afterEach(() => {
nock.cleanAll();
});
it('should create an action to request a password reset', (done) => {
nock('http://localhost:8080/')
.post('/password-reset-requests')
.reply(200);
var email = "test@gmail.com"
var addPasswordResetRequest = spy(() => {
return [
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}];
});
const expectedActions= [
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
];
const store = mockStore({}, expectedActions, done);
store.dispatch(Actions.addPasswordResetRequest());
});
});
So when I try to test with the above code: I get a fetch is not defined ReferenceError.
When I try to use a try,catch ala:
try{
const store = mockStore({}, expectedActions, done);
store.dispatch(Actions.addPasswordResetRequest(email));
done();
} catch(x) {
done(x);
}
I still get the same fetch is not defined error. Notice that I am the using Actions version, not the spied one.
When I use the spy() function, and do
const store = mockStore({}, expectedActions, done);
store.dispatch(addPasswordResetRequest());
Then I get the error:
Error: Expected [ { type: 'REQUEST_ADD_PASSWORD_RESET_REQUEST' }, { type: 'REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS' } ] to equal { type: 'REQUEST_ADD_PASSWORD_RESET_REQUEST' }
Not good, since the expected Action is the same as the return action. However if I do
var addPasswordResetRequest = spy(() => {
return {type: REQUEST_ADD_PASSWORD_RESET_REQUEST};
});
It times out, even after 30000ms.
But if I do:
describe('forgot password async actions', () => {
afterEach(() => {
nock.cleanAll();
});
it('should create an action to request a password reset', (done) => {
nock('http://localhost:8080/')
.post('/password-reset-requests')
.reply(200);
var email = "test@gmail.com"
var addPasswordResetRequest = spy(() => {
return {type: REQUEST_ADD_PASSWORD_RESET_REQUEST};
});
const expectedActions= [
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
];
//const store = mockStore({}, expectedActions, done);
//store.dispatch(addPasswordResetRequest());
try{
const store = mockStore({}, expectedActions, done);
store.dispatch(addPasswordResetRequest(email));
done();
} catch(x) {
done(x);
}
//console.log(actions);
//expect(actions.addPasswordResetRequest("email")).to.equal(expectedAction);
});
});
It passes. I don't know if that is considered sufficient for testing an asynchronous action because I am expecting to get both actions in order.
Also, if I do the above version without the try and catch, then it also times out.
I know I must be missing something very simple. I assume using nock would mock fetch when I was doing Actions.addPasswordResetRequest, but it still is being called. Is it because I am not calling fetch in the Action, but rather in a different file?
I also am a little hazy about the purpose of unit testing an asynchronous action. We just want to ensure that the correct sequence of actions is returned as a result of the input. So if we nock a 200 reply, we want a request, and then a success action to appear. Right?
Aucun commentaire:
Enregistrer un commentaire