Reputation: 13415
Question says it all. Given this function:
export function fetchBuilds() {
return dispatch => {
touchCookie();
dispatch(requestBuilds());
return request.get('/builds')
.withCredentials()
.use(AuthIntercept)
.then((response) => {
dispatch(receiveBuilds(response));
}, (error) => {
dispatch(receiveBuildsError(error.message));
});
};
}
what's the most effective testing strategy? I plan on mocking the AJAX request, but how do I assert that the return is what I expect?
Following on the heels of that, I'm also at a loss as to the best way to test the control flow for the function; or is that even something I should worry about?
The setTimeout
calls are ugly, but they seem to get the job done.
describe('Build actions', () => {
const testBuilds = [
{id: 1, name: 'some name'}
];
beforeEach(() => {
dispatchSpy = jasmine.createSpy('dispatch').and.callFake((cb) => {
switch (cb.type) {
case types.REQUEST_BUILDS:
return {
type: types.REQUEST_BUILDS
};
case types.RECEIVE_BUILDS:
return {
type: types.RECEIVE_BUILDS,
builds: testBuilds
};
default:
return null;
}
});
cookieSpy = spyOn(userActions, 'touchCookie');
requestSpy = spyOn(actions, 'requestBuilds').and.callThrough();
receiveSpy = spyOn(actions, 'receiveBuilds').and.callThrough();
});
it('should be able fetch builds', () => {
jasmine.Ajax.install();
const result = actions.fetchBuilds();
result(dispatchSpy);
expect(cookieSpy).toHaveBeenCalled();
expect(dispatchSpy).toHaveBeenCalledWith(actions.requestBuilds());
expect(requestSpy).toHaveBeenCalled();
let request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe(`/builds`);
request.respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(testBuilds)
});
setTimeout(() => {
expect(dispatchSpy).toHaveBeenCalledWith(actions.receiveBuilds(testBuilds));
setTimeout(() => {
expect(receiveSpy).toHaveBeenCalledWith(testBuilds);
}, 10);
}, 1);
});
});
Upvotes: 0
Views: 2055
Reputation: 747
This is definitely not an easy thing to test. I'd use Sinon for spies and stubs, and make it an async test. First, I would call the returned function in my test body. I would spy on touchCookie, dispatch, and requestBuilds, and make sure that they were called. I'd make sure that the return value of the returned function is a promise, and attach a .then in the test body that checks to see that dispatch was called with the results of receiveBuilds and receiveBuildsError, both of which I would stub. I would also spy on the Ajax call and make sure the correct url was requested.
Your test code will definitely be more lengthy than your actual function, but that's not really a bad thing. :-)
Upvotes: 1