0

I am learning to write unit tests for my angular app. My controller has several dependencies upon Resources, factories, services etc

angular.module('app').controller('Ctrl1',['$scope','Factory1','Factory2','Resource1','Resource2' ... and so on 

The Resource1, Resource2, etc of course fetch data from the server. Several of these resources are used to fetch data from the server and initialize $scope.

After reading innumerous tutorials all over the net, I have a few queries on the right way to write my jasmine tests

  1. In the beforeEach section of the jasmine test, am I suppose to provide all dependencies right away or should I provide only the ones I care about testing

  2. What I want to test is that Resource1 gets called and fetches some data and intializes some part of $scope then Resource2 gets called and fetches some data and initializes some other part of scope etc

What is the right way to perform the above. I mean am I actually suppose to fetch the data in the test or should I be using some mock http service. I know tutorials mention that we should use mock http service but then how will this test my controller since I am not actually fetching the right data.

This part is really confusing and I have yet to find a blog/article that explains this clearly (I might just write one once I figure things out.. I am sure others are confused too)

1 Answer 1

1

Where to Provide Dependencies

You should provide all of your dependencies in your first beforeEach statement. I mock/fake mine with SinonJs. This helps you take advantage of angular's dependency injection to isolate each piece of your application. You should never call a dependency and expect an actual instance of it to return data in a unit test, as that would increase the coupling of your code and make it far more brittle.

Mocking Resource Calls

For resource calls, I simply create a fake resource object with promises and whatnot included. You can then resolve or reject those promises and provide fake data to test your controller logic.

In the plunk below, I've essentially mocked out a whole promise chain. You simply tell your tests to either reject or resolve those promises, faking a successful or failure call to the resource. You then have to make sure your scope cycles with scope.$apply(). I actually forgot to do this which caused me quite a bit of trouble just now.

Conclusion

Here is the Plunk. Let me know if you need to see how I test the actual resource code in my repositories. In those services I have to actually mock out the HTTP calls, which Angular makes extremely easy.

I'm not sure any of this is "Best Practice" but it has worked for me. I learned the basics from looking at other people's source code and watching this Pluralsite video AngularJS Fundamentals which has a very small section on testing.

Useful Resources

  • Testing AngularJS Directives. This is the hardest thing to test and understand in Angular. Or at least it was for me.

  • This one is on Dependency Injection in Angular. I have it marked about where they start talking about unit testing.

  • This Plural Sight Course got me started with testing JavaScript in general. Very helpful for learning Jasmine if you are new to it.

  • AngularJS Github repo is very useful if you want to see Jasmine tests in action. Here is a set of tests that simulates a HTTP Backend.

Sign up to request clarification or add additional context in comments.

6 Comments

That's a very helpful answer. What if the module 'plunker' in your code is dependent on factories that belong to other modules.. how does the code change then.
It shouldn't change the code at all. The dependencies are not loading at all, just the Sinon stubs. So, your code does not have to be aware of where the actual code that is used in production comes from. Tonight at home I'll modify the plunk to demonstrate this with a service that uses resources.
I just got home and can't think. I'll try to update this with that question in mind tomorrow, or if worst comes to worst, this weekend.
thanks.. in the meantime.. what are some really good resources to learn jasmine testing.. Random articles and Angular help page is not very helpful
I added "Useful Resources" to my response. I'm sorry I don't have anything that is just amazing out of the box, but those videos would give you decent understanding. It took me quite a few days of reading, watching videos and looking at other libraries unit tests to understand them.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.