Angular Unit Testing
feat. Karma & Jasmine
Sources:
https://www.youtube.
com/channel/UCdaEMffiYgTf_E7uTMxM4og/videos
(files: https://github.com/mlassi/neosavvy)
http://slides.com/thebearingedge/testing-angular-js#/
(files:https://github.com/thebearingedge/test-
driving-angular-apps)
Setup Part 1: Karma & Jasmine
completely from scratch!
>npm init
creates a package.json
just go with the defaults
(keep pressing enter)
result should look something
like this -->
Setup Part 1: Karma & Jasmine
>npm install karma --save-dev
>npm install karma-jasmine --save-dev
>npm install karma-chrome-launcher --save-dev
(‘chrome’ can be replaced w/ur browser of choice)
why --save-dev?
https://www.npmjs.com/package/karma-jasmine
or you can install an older
version:
‘karma-jasmine@version’
← package.json
Setup Part 1: Karma & Jasmine
>karma init
if your command line doesn’t know wtf you meant:
now it should work. mindlessly hit enter until:
http://karma-runner.github.io/0.12/intro/installation.html
If you screw up these locations, karma
won’t be able to find your files.
Fortunately you can fix the locations
manually in your shiny new
karma.conf.js
Setup Part 2: Angular
mandatory:
>bower install angular
>bower install angular-mocks
depending on your Angular app:
angular-route, angular-resource, etc.
(if your command line can’t bower: npm install bower -g)
Setup Part 2: Angular
karma still has no idea these files exist, so tell it:
FINALLY...
>karma start karma.conf.js
← karma.conf.js
hey, at least it’s running...
Basic Test Structure - ‘Describe’ Block
describe(‘some module or component’, function( ){ });
what goes inside the { } ?
1st - stuff you want to apply to all tests in the describe block
2nd - your actual test specs i.e. the “it(‘should...’ )” things
p.s. suffix all your unit test files with “spec.js” or other devs will hate you…
FOREVER.
Basic Test Structure - Setup/Teardown
what goes inside the ‘describe’ block { } ?
1st - stuff you want to apply to all tests in the describe block
setup stuff:
var var1, var2… ← available to all tests in block
beforeEach(function( ){ #1 #2 #3 })
#1 - module(‘moduleName’);
#2 - inject(function(mocks, components){ });
#3 - other setup functions
Basic Test Structure - Setup/Teardown
what goes inside the describe block { } ?
setup stuff continued:
beforeEach(function( ){ #1 #2 #3 })
#1 - module(‘moduleName’);
^ registers module components with $injector
#2 - inject(function(mocks, components){ });
^ injects registered components (can also use ‘$injector.get’)
#3 - other setup functions
^ not always needed, may be before or after #1 and #2
Basic Test Structure - Setup/Teardown
what goes inside the ‘describe’ block { } ?
1st - stuff you want to apply to all tests in the describe block
teardown stuff (happens after each test):
afterEach(function( ){ });
- not used as often as ‘beforeEach’
- commonly used with $httpBackend:
afterEach(function( ){
$httpBackend.verifyNoOutstandingExpectaction();
$httpBackend.verifyNoOutstandingRequest(); });
Basic Test Structure - ‘It’ Block
what goes inside the ‘describe’ block { } ?
2nd - your actual test specs i.e. the “it(‘should...’ )” things
it(‘should do a thing’, function( ) { #1 #2 });
#1 - setup vars and/or functions ← may be optional
#2 - expect(thing).someMatcher(thing2);
^ THIS IS THE TEST ASSERTION
- nothing is actually tested without the assertion
- try not to have more than one assertion per ‘it’ block
Basic Test Structure - ‘It’ Block
related ‘it’ blocks may be wrapped in another describe block:
describe(‘main module or component’, function( ) {
describe(‘component or behavior’, function( ) {
it(‘should do a thing’, function( ) {
expect(thing).someMatcher(thing2);
});
it(‘should do another thing’, function( ) {
expect(thing3).someMatcher(thing4);
});
});
})
Matchers
expect(thing).someMatcher(thing2);
list of matchers:
https://jasmine.github.io/2.2/introduction.html
some important ones:
.toBe( ) ← equivalent to ‘===’
.toEqual( ) ← equivalent to ‘==’
^ docs make it seem like toEqual doesn’t work on arrays but it
does when I try it… ¯_(ツ)_/¯
Mocks (Fake it ‘til you make it!)
https://code.angularjs.org/1.3.15/docs/api/ngMock
Your new best friend if you have a $http method:
https://code.angularjs.org/1.3.15/docs/api/ngMock/service/$httpBackend
Basic Controller Test
someCtrl.js
angular
.module(‘ngmod’,[ ])
.controller
(‘someCtrl’,
function($scope) {
$scope.stuff
= [1,2,3];
});
someCtrlSpec.js
describe(‘someCtrl’,function() {
var scope = { };
beforeEach(function() { module(‘ngmod’);
inject(function($controller) {
$controller(‘someCtrl’,{$scope:
scope});
});
});
it(‘should model “stuff” ’,function() {
expect(scope.stuff).toEqual([1,2,3]);
})
$httpBackend Test
httpCtrl.js
angular.module('module2',[])
.controller('httpCtrl',function($http)
{
var main = this;
main.stuff = [];
$http.get('https://herpderp.
firebaseio.com/').success(function (data)
{
main.stuff = data;
});
});
httpCtrlSpec.js
ONTO THE
~*~LIVE CODING!~*~
because I’m too lazy to make more slides

AngularJS Unit Testing w/Karma and Jasmine

  • 1.
  • 2.
  • 3.
    Setup Part 1:Karma & Jasmine completely from scratch! >npm init creates a package.json just go with the defaults (keep pressing enter) result should look something like this -->
  • 4.
    Setup Part 1:Karma & Jasmine >npm install karma --save-dev >npm install karma-jasmine --save-dev >npm install karma-chrome-launcher --save-dev (‘chrome’ can be replaced w/ur browser of choice) why --save-dev? https://www.npmjs.com/package/karma-jasmine or you can install an older version: ‘karma-jasmine@version’ ← package.json
  • 5.
    Setup Part 1:Karma & Jasmine >karma init if your command line doesn’t know wtf you meant: now it should work. mindlessly hit enter until: http://karma-runner.github.io/0.12/intro/installation.html If you screw up these locations, karma won’t be able to find your files. Fortunately you can fix the locations manually in your shiny new karma.conf.js
  • 6.
    Setup Part 2:Angular mandatory: >bower install angular >bower install angular-mocks depending on your Angular app: angular-route, angular-resource, etc. (if your command line can’t bower: npm install bower -g)
  • 7.
    Setup Part 2:Angular karma still has no idea these files exist, so tell it: FINALLY... >karma start karma.conf.js ← karma.conf.js hey, at least it’s running...
  • 8.
    Basic Test Structure- ‘Describe’ Block describe(‘some module or component’, function( ){ }); what goes inside the { } ? 1st - stuff you want to apply to all tests in the describe block 2nd - your actual test specs i.e. the “it(‘should...’ )” things p.s. suffix all your unit test files with “spec.js” or other devs will hate you… FOREVER.
  • 9.
    Basic Test Structure- Setup/Teardown what goes inside the ‘describe’ block { } ? 1st - stuff you want to apply to all tests in the describe block setup stuff: var var1, var2… ← available to all tests in block beforeEach(function( ){ #1 #2 #3 }) #1 - module(‘moduleName’); #2 - inject(function(mocks, components){ }); #3 - other setup functions
  • 10.
    Basic Test Structure- Setup/Teardown what goes inside the describe block { } ? setup stuff continued: beforeEach(function( ){ #1 #2 #3 }) #1 - module(‘moduleName’); ^ registers module components with $injector #2 - inject(function(mocks, components){ }); ^ injects registered components (can also use ‘$injector.get’) #3 - other setup functions ^ not always needed, may be before or after #1 and #2
  • 11.
    Basic Test Structure- Setup/Teardown what goes inside the ‘describe’ block { } ? 1st - stuff you want to apply to all tests in the describe block teardown stuff (happens after each test): afterEach(function( ){ }); - not used as often as ‘beforeEach’ - commonly used with $httpBackend: afterEach(function( ){ $httpBackend.verifyNoOutstandingExpectaction(); $httpBackend.verifyNoOutstandingRequest(); });
  • 12.
    Basic Test Structure- ‘It’ Block what goes inside the ‘describe’ block { } ? 2nd - your actual test specs i.e. the “it(‘should...’ )” things it(‘should do a thing’, function( ) { #1 #2 }); #1 - setup vars and/or functions ← may be optional #2 - expect(thing).someMatcher(thing2); ^ THIS IS THE TEST ASSERTION - nothing is actually tested without the assertion - try not to have more than one assertion per ‘it’ block
  • 13.
    Basic Test Structure- ‘It’ Block related ‘it’ blocks may be wrapped in another describe block: describe(‘main module or component’, function( ) { describe(‘component or behavior’, function( ) { it(‘should do a thing’, function( ) { expect(thing).someMatcher(thing2); }); it(‘should do another thing’, function( ) { expect(thing3).someMatcher(thing4); }); }); })
  • 14.
    Matchers expect(thing).someMatcher(thing2); list of matchers: https://jasmine.github.io/2.2/introduction.html someimportant ones: .toBe( ) ← equivalent to ‘===’ .toEqual( ) ← equivalent to ‘==’ ^ docs make it seem like toEqual doesn’t work on arrays but it does when I try it… ¯_(ツ)_/¯
  • 15.
    Mocks (Fake it‘til you make it!) https://code.angularjs.org/1.3.15/docs/api/ngMock Your new best friend if you have a $http method: https://code.angularjs.org/1.3.15/docs/api/ngMock/service/$httpBackend
  • 16.
    Basic Controller Test someCtrl.js angular .module(‘ngmod’,[]) .controller (‘someCtrl’, function($scope) { $scope.stuff = [1,2,3]; }); someCtrlSpec.js describe(‘someCtrl’,function() { var scope = { }; beforeEach(function() { module(‘ngmod’); inject(function($controller) { $controller(‘someCtrl’,{$scope: scope}); }); }); it(‘should model “stuff” ’,function() { expect(scope.stuff).toEqual([1,2,3]); })
  • 17.
    $httpBackend Test httpCtrl.js angular.module('module2',[]) .controller('httpCtrl',function($http) { var main= this; main.stuff = []; $http.get('https://herpderp. firebaseio.com/').success(function (data) { main.stuff = data; }); }); httpCtrlSpec.js
  • 18.
    ONTO THE ~*~LIVE CODING!~*~ becauseI’m too lazy to make more slides