Wednesday, October 30, 2013

AngularJS Unit testing - A helper for stubbing dependent methods that return promises

Deferreds and Promises have changed javascript development for the better. They offer an escape from callback hell. AngularJS supports a version of promises heavily inspired by the popular q library.

This is great however testing mocking out angularjs service dependencies which return promises was less great!

I want to test this:


Incidentally this kind of pattern is becoming more common now promise unwrapping is gone.

What I wanted:
  • A way to easily mock the "fetchData" service method
  • Capability to assert "fetchData" was called the with right arguments ( using jasmine spies)
  • The mock "fetchData" should return a promise so I can call "then" and use utilities such as $q.all
  • As little boiler plate code as possible
So I wrote this little helper:



And here is what the full test looks like:

Here is a full working jsfiddle

There's potential to expand this out having more functionality such as dealing with failing promises and giving more control over when the promise is resolved etc. If you think that's a good idea let me know in the comments.




4 comments:

  1. Nice!
    Since spies in Jasmine have a .andReturn function, how about adding a .andResolveWith and a .andRejectWith functions to your spy? I've done that in this gist: https://gist.github.com/matiboy/7243743

    ReplyDelete
  2. Good idea!

    The call to $q needs to be lazy to work as $q might not be injected yet.

    Also I like the brevity of my approach but I think both can work together. I'll write an update. Thanks!

    ReplyDelete
  3. Thanks that's great - a nice way of organising the test structure.

    ReplyDelete
  4. Awesome look at some real test examples. Thanks for posting this. I'd love a post about how you structure the app with browserify.

    ReplyDelete