Recently, I have been playing around with Javascript and AngularJS. Predominantly, being a backend developer, this was a good challenge.
And prior I had no extensive experience on Javascript nor AngularJS. So, I am a newbie.
However, I thought to blog some of my learnings, specially when it comes to testing the code.
This tutorial only touches the basic essence of mocking promises in Javascript code when unit testing.
The sample code for this project can be found here.
Prerequisites
- NodeJS installed. You can find out more at http://nodejs.org/
- Git
Step 1: Cloning the project
$ git clone https://github.com/fazlan/angularjs.git
Step 2: Moving to the sample folder
$ cd angularjs/angular-mock-promises-sample
Step 3: Installing required node dependencies
{ "name": "mock-service", "version": "1.0.0", "description": "", "author": "", "license": "ISC", "devDependencies": { "jasmine-core": "^2.1.3", "karma": "^0.12.31", "karma-jasmine": "^0.3.5", "karma-phantomjs-launcher": "^0.1.4", "phantomjs": "^1.9.13" } }
$ npm install -g karma-cli
The above is optional. You can skip the above if you have already installed karma-cli globally
$ npm install
This will install all the node dependencies in the package.json
Step 4: Installing required bower dependencies
{ "name": "mock-service", "version": "0.0.0", "license": "MIT", "devDependencies": { "angular": "~1.3.11", "angular-mocks": "~1.3.11" } }
$ npm install -g bower The above is optional. You can skip the above if you have already installed bower globally
$ bower install
This will install all the bower dependencies in the bower.json
Step 5: Karma configuration
// Karma configuration // Generated on Tue Jan 27 2015 14:23:24 GMT+1100 (Tasmania Daylight Time) module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser files: [ 'bower_components/angular/angular.js', 'bower_components/angular-mocks/angular-mocks.js', 'app/src/**/*.js', 'app/test/**/*_spec.js' ], // list of files to exclude exclude: [ ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: false, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['PhantomJS'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: true }); };
Step 6: Jasmine test with mocks
'use strict'; describe('The Mocked Weather Controller', function () { var scope; beforeEach(function () { // load the module angular.mock.module('weather.module'); // inject the angular services inject(function ($controller, $rootScope, $q) { scope = $rootScope.$new();
// mock the promise via $q service of angular var mockedOpenweatherMapAPI = { getWeather: function () { var deferred = $q.defer(); deferred.resolve(openweatherMapJsonResponse()); return deferred.promise; } }; $controller('WeatherController', {$scope: scope, WeatherService: mockedOpenweatherMapAPI}); }); }); it('Returns the name of the city', function () { scope.$digest(); expect(scope.weather).toEqual('Melbourne'); }); it('Returns the temperature details of Melbourne', function () { scope.$digest(); expect(scope.temperature.temp).toEqual(23.3); expect(scope.temperature.humidity).toEqual(45); expect(scope.temperature.temp_min).toEqual(21.3); expect(scope.temperature.temp_max).toEqual(25.4); }); it('Returns the weather summary details of Melbourne', function () { scope.$digest(); expect(scope.weatherInfo.main).toEqual('Clear'); expect(scope.weatherInfo.description).toEqual('Sky is Clear'); }); function openweatherMapJsonResponse() { return { "list": [ { "name": "Melbourne", "main": { "temp": 23.3, "humidity": 45, "pressure": 1016.2, "temp_min": 21.3, "temp_max": 25.4 }, "weather": [ { "id": 800, "main": "Clear", "description": "Sky is Clear", "icon": "01d" } ] } ]}; } });
NOTE: Make sure to call the $digest() method on your scope variable on each test before you expect() results.
scope.$digest()
Step 7: Running the Jasmine tests
$ karma start karma.config.js
You'll see all your tests being run and their results.
Summary:
In this article, we looked at how to test promises in Javascript with mocked data. You can find the sample code for this post here.
No comments:
Post a Comment