I've created a small learning project in Redux, and have essentially copied the middleware for asynchronous actions from the documentation. Now I want to write some tests for it, to make sure that it will work fine after I change around some things.
To write my tests, I'm using Mocha, with chai, chai-as-promised and sinon.
I have no problems with redux in any way, but I'm unsure of how to test things.
The relevant code from the middleware:
export default function callApiMiddleware({ dispatch }) {
return next => action => {
// ... various checks
const [ requestType, successType, errorType ] = types;
dispatch({ ...payload, type: requestType });
return callApi().then(
response => dispatch({ ...payload, type: successType, response }),
error => dispatch({ ...payload, type: errorType, error })
);
}
}
The middleware dispatches the appropriate action whether the promise is fulfilled or rejected.
To test this, I'm stubbing out the dispatch function, along with others, and I also pass in a dummy promise, that I fulfill or reject depending on what I want to test.
A test I have written looks like this:
it('should trigger success action when successful', () => {
let promise = callApiMiddleware({ dispatch, getState })(next)({
...action,
callApi: () => new Promise((resolve, reject) => resolve('SUCCESS'))
});
return expect(promise).to.eventually.be.fulfilled;
});
This works fine, but the first problem I ran into was when I tried to simulate a rejected promise that could result from no internet connection, so I wrote this test:
it('should trigger failure action when failure occurs', () => {
let promise = callApiMiddleware({ dispatch, getState })(next)({
...action,
callApi: () => new Promise((resolve, reject) => reject('ERROR'))
});
return expect(promise).to.eventually.be.rejected;
});
But this fails with the following message:
AssertionError: expected promise to be rejected but it was fulfilled with undefined
Expected :[undefined]
Actual :[undefined]
This makes no sense to me, since I clearly pass in a promise that's only function is to be rejected.
My other problem is that I also want to make other assertions, that don't necessarly have anything to do with the promise itself, but have to be evaluated when the promise finishes e.g. I want to assert that the dispatch
method was called twice. The dispatch
method itself is stubbed out in the test using sinon in order to perform the desired assertions. Potentially, I want to make multiple assertions in this way.
I have tried the following:
it('should trigger success action when successful', () => {
let promise = callApiMiddleware({ dispatch, getState })(next)({
...action,
callApi: () => new Promise((resolve, reject) => resolve('SUCCESS'))
});
return Q.all([
expect(promise).to.eventually.be.fulfilled,
expect(dispatch).to.eventually.be.calledTwice
]);
});
But this returns some very large error that simply tells me that dispatch
is not thenable
i.e. not a promise.
I am out of ideas on how to do this, so any input would greatly be appreciated.
Aucun commentaire:
Enregistrer un commentaire