angularjs unit testing w/karma and jasmine
TRANSCRIPT
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 initcreates a package.jsonjust 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 initif 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 newkarma.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’ Blockdescribe(‘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/Teardownwhat 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 blockbeforeEach(function( ){ #1 #2 #3 })
#1 - module(‘moduleName’);#2 - inject(function(mocks, components){ });#3 - other setup functions
Basic Test Structure - Setup/Teardownwhat 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/Teardownwhat 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’ Blockwhat 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’ Blockrelated ‘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 TestsomeCtrl.js
angular.module(‘ngmod’,[ ]).controller(‘someCtrl’,function($scope) {
$scope.stuff = [1,2,3];
});
someCtrlSpec.jsdescribe(‘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 TesthttpCtrl.jsangular.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