In this post I quickly want to go over the difference between using spyOn for methods of the object under tests and using spyOn to spy on methods of an object that is a dependency of the object under test. This is another post that's all about "testing one thing at a time" in your AngularJS unit tests by "using the real thing" for the object or method under test and using spyOn to fake rest.
Use the real thing for the object / method under test,
Make a New Unit Test File
Using spyOn To Make Fake Implementations for Methods on the Object Under Test
Suppose we're testing the "calculateScrollAmount" method, but for some reason we want to define a fake implementation for "getContainerHeight" so that it just automatically returns 500. In this code snippet below I'm spying on getContainerHeight, another method in AgendaAutoScroller and defining a fake implementation for it that just returns 500. The point of doing this is that the calculateScroll method calls 'getContainerHeight' at some point when it's invoked so in order for the assertion that calls "calculateScroll" you need to have getContainerHeight returning something valid (like 500).
Using spyOn for Methods of Dependency Objects
You can also spyOn methods that are calling from dependencies within the function you are trying to test. Suppose the instead of 'getContainerHeight' being a method on AgendaAutoScroller, it's instead a method of a different AngularJS "service service", let's call this new one HeightTracker. So in our AgendaAutoScroller service when it's created we inject HeightTracker, and we later call HeightTracker.getcontainerHeight() from inside of AgendaAutoScroller.calculateScroll().
So in our unit test we can inject this dependency, and just spy on it's methods. Because they are the exact same name, Angular knows to use this "spied on" version of the HeightTracker dependency when creating AgendaAutoScroller.
Bonus Tip: "Spy on" Variables
The actual Jasmine method spyOn won't work for variables, but in therms of being able to create your own fake implementation / value for unit tests in the same section of your file when you would spyOn your methods you can just manually set variables of either your object under test or any dependencies simply by injecting them and setting the values. In the example below, when AgendaAutoScroller is created and has HeightTracker injected into it the value of HeightTracker.initialValue is true.
The posts on this site are written and maintained by Jim Lynch. About Jim...