31
ANGULARJS UNIT TESTING Hor Norin 7 November 2016

AngularJS Unit Testing

Embed Size (px)

Citation preview

Page 1: AngularJS Unit Testing

ANGULARJS UNIT TESTING

Hor Norin7 November 2016

Page 2: AngularJS Unit Testing

Objective & Goals• Why unit test?• Basic Setup• Jasmine• AngularJS Testing• Mocking & Stubbing• Best Practices

Page 3: AngularJS Unit Testing

WHY UNIT TESTING?

Page 4: AngularJS Unit Testing

Why Unit Testing?• Reduce bug• Improve code quality• Good documentation• Defend against other programmers• Make you feel confident

Page 5: AngularJS Unit Testing

BASIC SETUP

Page 6: AngularJS Unit Testing

Tools You Need• Node.js• Karma• Jasmine• Angular Mock• Browser

Page 7: AngularJS Unit Testing

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

Setup Karma• npm install karma-cli –g• karma init• karma start

Page 9: AngularJS Unit Testing

Configuration Options• frameworks• files• exclude• browsers• basePath• preprocessors• singleRun• autoWatch

Page 10: AngularJS Unit Testing

JASMINE

Page 11: AngularJS Unit Testing

Functions• Suite: describe• Spec: it• Setup: beforeEach• Teardown: afterEach• Expectation: expect

Page 12: AngularJS Unit Testing

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

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

Custom MatcherExample:

Page 15: AngularJS Unit Testing

ANGULARJS TESTING

Page 16: AngularJS Unit Testing

Loading Moduledescribe('App', function() { beforeEach(module(’App'));

it('1 + 1 should equal 2', function() { // some expectations });});

Page 17: AngularJS Unit Testing

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

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

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

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

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

MOCKING & STUBBING

Page 23: AngularJS Unit Testing

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

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

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

BEST PRACTICES

Page 27: AngularJS Unit Testing

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

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

RESOURCES & REFERENCES

Page 30: AngularJS Unit Testing

Resources & References• https://jasmine.github.io/2.0/introduction• https://docs.angularjs.org/api/ngMock

Page 31: AngularJS Unit Testing

Further Reading• https://docs.angularjs.org/guide/e2e-testing• https://github.com/angular/protractor