Unit testing in AngularJS - Mocking Services and Promises
21 Aug 2014
In Angular everything seems to have a steep learning curve and unit testing an Angular app definitely doesn’t escape this paradigm.
When I started with TDD and Angular I felt that I was spending twice (maybe more) as much time figuring out just how to test and maybe even more
just getting my tests set up correctly. But as Ben Nadel put it in his blog there are ups and downs in the angular learning process -
his graph is definitely my experience with Angular.
However as I have progressed in learning Angular and unit testing as well, now I feel that I am spending much less time setting up tests
and much more time making tests go from red to green - which is a good feeling.
I have come across different methods of setting up my unit test to mock services and promises.
So onto the code I am sure you don’t wanna listen to some guy blab about his love, err accomplishments learning a framework, especially when his blog is about JS and beer - how drunk could he be?
This is how I started out mocking my services and promises, I’ll use a controller, but services and promises can be mocked in other places using the same technique.
This worked, but as time went on I thought there must be a better way. For one, I hated the
thing, and if I wanted to reinitialise the controller then I had to pull it out of the beforeEach block, and inject it individually into each test, making our tests definitely not DRY.
There has to be a better way…
Then I came across another post, blog, stackoverflow example (you pick it I was probably there), and I saw the use of the $q library.
D’oh!
Why set up a whole mock promise when we can just use the tool that Angular gives us. Our code looks cleaner and it’s much more intuitive
no ugly promise.then.mostRecent thing. Then to DRY everything out, wrap the controller instantiation in a function so we can have more control over how the controller behaves
for setting up our different test conditions through the use of parameters and CONSTANTS. Now we’re getting sommewhere.
Next in the iteration of unit testing was this.
This started to feel like the way it should be set up. We can mock what we need to mock, we can set our promise to resolve and reject.
We can truly test the two possible outcomes. This feels good.