Mocking Functions That Return Promises

I have been writing a funky little chrome extension for GitHub, which lets us view and update the labels on Pull Requests – a feature that would be easy for GitHub to implement but sorely lacking. You can check out this extension here:

While I was writing unit tests, I wanted to test a directive that relied upon a service that returns a promise.  I wanted to mock out the service, itself, rather than get drawn into setting up mock $httpBackend responses.  Initially, I started writing out something like this:

This allowed me to test that the getCheckedLabels method had been called but then I wanted to get this spy to return some mock data via the promise.  I started thinking I was going to have to write a load of boilerplate code to store and then trigger the success handler in my test, which looked really ugly.

Then I thought I would be clever and create a generic mock promise object that I could use in all these situations with some kind of mockPromise.resolveWith('myMockData') API. As I was about to do this the obvious truth that this had already been done slapped me in the face.  In tests, I just want a promise that is either resolved or rejected already, so I just create one using $q:

Simple, eh?  This mocks out the getCheckedLabels method with a function that returns an already resolved promise.  The test is clean and simple and does what I want.

One thought on “Mocking Functions That Return Promises

  1. I like it. I’d also like to add the following:

    If you need to mock a promise resulting in a failure, you can use $q.reject();

    // simulate a rejection.
    spyOn(githubAPI, 'getCheckedLabels').andReturn( $q.reject({ status: 400, data: 'Your mother was a hamster!' }) );

Comments are closed.