So, I will be using an overly simplistic Angular JS controller as a “proof of concept” to demonstrate how we can make our tests cleaner. Have a look at this controller, it contains a call to a service, through which it receives data and upon resolution of the promise, it attaches it to the view via the “vm” variable.
Note: I am using the “Controller As” syntax so bye bye $scope and hello cleanliness.
To test this controller I needed to mock the call to the “dataservice” which returns a mocked response. There are 3 ways we can mock the response.
The Good: because it works!
The Better: because we are getting there …
Declare the mock object in a mock Angular JS factory and expose it via a return object. This approach was blogged earlier here. The problem with this approach is that the mock Angular JS factory gets messier as the objects are added to it. It becomes one long/big file making it harder to maintain. Okay ….
The Best: Bingo!
Declare the mock object in a JSON file, load it inside an Angular JS factory and expose it via a return object. I find this approach to be the best. Each object has its own file and is cleanly loaded into the Angular JS mock factory. The separation of objects into their own files make it a ton easier to maintain. That’s more like it !
In order to achieve the “Best” way to mock objects, we will make use of “jQuery-Jasmine” through which we will load the objects form the JSON file but it requires little bit of configuration so lets go through it step by step:
1. Install jquery-jasmine as a development dependency via npm
Run “npm install jquery-jasmine –save-dev” on the root of your project via terminal/bash/cmd.
2. Include jquery, jquery-jasmine as “files to be loaded”
Since I am using Karma to run my Jasmine tests, I only need a simple addition to the files array in my karma.conf.js file. See image below step 3.
3. Include the JSON files as “files to be loaded”
Similar to the previous step, add the JSON files to the files array in the karma.conf.js.
4. Let Jasmine know from where to load the JSON files from
I have a separate Angular JS module for my mocks, so the place where I declare my module is the place I use to declare the relative path of my tests which would be loaded on the browser.
Note: This path is something karma makes when it loads the tests from the file system onto the browser and can change in the upcoming releases.
This is it for the configuration, now we need to create an Angular JS factory which would load the JSON files and expose them as objects in our test files. Here is the JSON file and how we load it into our mock Angular JS factory …
And finally…. This is how the tests look like.
I must say, transitioning from good to better to best feels a lot satisfactory.
All of you can now safely get up from your chairs and do this ….