angularjs unit testing
TRANSCRIPT
![Page 1: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/1.jpg)
ANGULARJS UNIT TESTING
Hor Norin7 November 2016
![Page 2: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/2.jpg)
Objective & Goals• Why unit test?• Basic Setup• Jasmine• AngularJS Testing• Mocking & Stubbing• Best Practices
![Page 3: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/3.jpg)
WHY UNIT TESTING?
![Page 4: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/4.jpg)
Why Unit Testing?• Reduce bug• Improve code quality• Good documentation• Defend against other programmers• Make you feel confident
![Page 5: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/5.jpg)
BASIC SETUP
![Page 6: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/6.jpg)
Tools You Need• Node.js• Karma• Jasmine• Angular Mock• Browser
![Page 7: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/7.jpg)
Package.json{ "name": "jasmine", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "karma start" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "angular": "^1.5.8" }, "devDependencies": { "angular-mocks": "^1.5.8", "jasmine-core": "^2.5.2", "karma": "^1.3.0", "karma-jasmine": "^1.0.2", "karma-phantomjs-launcher": "^1.0.2" }}
![Page 8: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/8.jpg)
Setup Karma• npm install karma-cli –g• karma init• karma start
![Page 9: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/9.jpg)
Configuration Options• frameworks• files• exclude• browsers• basePath• preprocessors• singleRun• autoWatch
![Page 10: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/10.jpg)
JASMINE
![Page 11: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/11.jpg)
Functions• Suite: describe• Spec: it• Setup: beforeEach• Teardown: afterEach• Expectation: expect
![Page 12: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/12.jpg)
Matchersexpect(array).toContain(member);expect(fn).toThrow(string);expect(fn).toThrowError(string);expect(instance).toBe(instance);expect(mixed).toBeDefined();expect(mixed).toBeFalsy();expect(mixed).toBeNull();expect(mixed).toBeTruthy();expect(mixed).toBeUndefined();expect(mixed).toEqual(mixed);expect(mixed).toMatch(pattern);expect(number).toBeCloseTo(number, decimalPlaces);expect(number).toBeGreaterThan(number);expect(number).toBeLessThan(number);expect(number).toBeNaN();expect(spy).toHaveBeenCalled();expect(spy).toHaveBeenCalledTimes(number);expect(spy).toHaveBeenCalledWith(...arguments);
![Page 13: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/13.jpg)
Custom Matcher• Use addMatchers• Factory object with factory function• Return object with compare function• Result of compare must contains pass and message property
![Page 14: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/14.jpg)
Custom MatcherExample:
![Page 15: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/15.jpg)
ANGULARJS TESTING
![Page 16: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/16.jpg)
Loading Moduledescribe('App', function() { beforeEach(module(’App'));
it('1 + 1 should equal 2', function() { // some expectations });});
![Page 17: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/17.jpg)
Controllerdescribe('SomeController', function() { var $scope, $controller;
beforeEach(function() { module('App'); inject(function($rootScope, _$controller_) { $scope = $rootScope.$new(); $controller = _$controller_; }); });
it('expect someModel to equal someValue', function() { var ctrl = $controller('SomeController', { $scope: $scope });
// $scope style expect($scope.someModel).toEqual(someValue); // controllerAs style expect(ctrl.someModel).toEqual(someValue); });});
![Page 18: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/18.jpg)
Componentdescribe('SomeComponent', function() { var $componentController, $scope;
beforeEach(function() { module('App');
inject(function($rootScope, _$componentController_) { $scope = $rootScope.$new(); $componentController = _$componentController_; }); });
it('expect someModel to equal someValue', function() { var component = $componentController('SomeComponent', null); expect(component.someModel).toEqual(someValue); });});
![Page 19: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/19.jpg)
Directivedescribe('Greeting', function() { var $scope, $compile;
beforeEach(function() { module('App'); inject(function($rootScope, _$compile_) { $scope = $rootScope.$new(); $compile = _$compile_; }); });
it('should contain greeting text', function() { var el = $compile('<greeting name="Norin"></greeting>')($scope); // fire all watchers so that expression // like {{ 1 + 1 }} will be evaluate $scope.$digest(); expect(el.html()).toContain('Hello Norin'); });});
![Page 20: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/20.jpg)
Servicedescribe('Calculator', function() { var $scope, calculator;
beforeEach(function() { module('App'); inject(function($rootScope, _calculator_) { $scope = $rootScope.$new(); calculator = _calculator_; }); });
it('should return sum of two value', function() { expect(calculator.sum(10, 20)).toEqual(30); });});
![Page 21: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/21.jpg)
Filterdescribe('Reverse', function() { var $scope, $filter;
beforeEach(function() { module('App'); inject(function($rootScope, _$filter_) { $scope = $rootScope.$new(); $filter = _$filter_; }); });
it('should make text reverse', function() { var reverseText = $filter('reverse')('Hello'); expect(reverseText).toEqual('olleH'); });});
![Page 22: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/22.jpg)
MOCKING & STUBBING
![Page 23: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/23.jpg)
Stub Object MethodspyOn(someObj, 'someMethod').and.returnValue(3);expect(someObj.someMethod()).toEqual(3);
spyOn(someObj, 'someMethod').and.callFake(function() { return 10;});expect(someObj.someMethod()).toEqual(10);
![Page 24: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/24.jpg)
Message Expectationvar norin = { info: function() { return 'Name: Norin, Gender: Male'; }};
function greeting(person) { console.log(person.info());}
spyOn(norin, 'info');greeting(norin);
expect(norin.info).toHaveBeenCalled();expect(norin.info.calls.count()).toBe(1);
![Page 25: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/25.jpg)
Mock API Request$httpBackend.when('GET', 'http://example.com/search?q=product1').respond(200, [1,2]);
var products = null;expect(products).toBeNull();productService.search('product1') .then(function(res) { products = res.data; }) .catch(function(error) { products = []; });
$httpBackend.flush();expect(products).not.toBeNull();expect(products.length).toBe(2);
![Page 26: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/26.jpg)
BEST PRACTICES
![Page 27: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/27.jpg)
Things to Be Done• Test case should be done in isolation• Make use of custom matcher• Reactor out code if need
![Page 28: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/28.jpg)
Things to Avoid• Directly use global variable & function• Nest describe block too deep• DRY too much makes it less readable
![Page 29: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/29.jpg)
RESOURCES & REFERENCES
![Page 30: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/30.jpg)
Resources & References• https://jasmine.github.io/2.0/introduction• https://docs.angularjs.org/api/ngMock
![Page 31: AngularJS Unit Testing](https://reader035.vdocuments.mx/reader035/viewer/2022070519/58ed2ba01a28abab6c8b46a9/html5/thumbnails/31.jpg)
Further Reading• https://docs.angularjs.org/guide/e2e-testing• https://github.com/angular/protractor