Unit Testing AngularJS ControllersAs
Testing Patterns
- Suggested Setup
- Data type
- Method use
- Have a good pattern?
Example implementation of these testing patterns
####Suggested Controller As Unit Test Setup ↑
# CoffeeScript describe 'Controller: myCtrl2 as ctrl', -> myCtrl2 = scope = mySvc = null # Initialize the controller and scope beforeEach -> # Load the controller's module module 'myApp' # Provide any mocks needed module ($provide) -> $provide.value 'mySvc', new MockMySvc() # Make sure CoffeeScript doesn't return anything null # Inject angular constructs otherwise, # you will need to inject these into each test inject ($controller, _mySvc_) -> scope = {} mySvc = _mySvc_ myCtrl2 = $controller 'myCtrl2 as ctrl', $scope: scope it 'should exist', -> expect(!!myCtrl2).toBe yes describe 'when created', -> # Add specs describe 'when destroyed', -> # Add specs
// JavaScript describe('Controller: myCtrl2 as ctrl', function () { var myCtrl2, scope, mySvc; // Initialize the controller and scope beforeEach(function () { // Load the controller's module module('myApp'); // Provide any mocks needed module(function ($provide) { $provide.value('mySvc', new MockMySvc()); }); // Inject in angular constructs otherwise, // you would need to inject these into each test inject(function ($controller, _mySvc_) { scope = {}; mySvc = _mySvc_; myCtrl2 = $controller('myCtrl2 as ctrl', { $scope: scope }); }); }); it('should exist', function () { expect(!!myCtrl2).toBe(true); }); describe('when created', function () { // Add specs }); describe('when destroyed', function () { // Add specs }); });
My controller should:
#####attach myThing to the scope ↑
# CoffeeScript it 'should define a myThing property', -> expect(scope.ctrl.myThing).toBeDefined()
// JavaScript it('should define a myThing property', function () { expect(scope.ctrl.myThing).toBeDefined(); });
#####attach myArray to the scope ↑
# CoffeeScript it 'should provide a myArray property', -> expect(scope.ctrl.myArray instanceof Array).toBe true
// JavaScript it('should provide a myArray property', function () { expect(scope.ctrl.myArray instanceof Array).toBe(true); });
#####attach myBoolean to the scope ↑
# CoffeeScript it 'should provide a boolean myBoolean property', -> expect(typeof scope.ctrl.myBoolean).toBe 'boolean'
// JavaScript it('should provide a boolean myBoolean property', function () { expect(typeof scope.ctrl.myBoolean).toBe('boolean'); });
#####attach myDate to the scope ↑
# CoffeeScript it 'should provide a myDate property', -> expect(scope.ctrl.myDate instanceof Date).toBe true
// JavaScript it('should provide a myDate property', function () { expect(scope.ctrl.myDate instanceof Date).toBe(true); });
#####attach myMethod to the scope ↑
# CoffeeScript it 'should provide a myMethod function', -> expect(typeof scope.ctrl.myMethod).toBe 'function'
// JavaScript it('should provide a myMethod function', function () { expect(typeof scope.ctrl.myMethod).toBe('function'); });
#####attach myNull to the scope ↑
# CoffeeScript it 'should provide a myNull property', -> expect(scope.ctrl.myNull).toBe null
// JavaScript it('should provide a myNull property', function () { expect(scope.ctrl.myNull).toBe(null); });
#####attach myNumber to the scope ↑
# CoffeeScript it 'should provide a myNumber property', -> expect(typeof scope.ctrl.myNumber).toBe 'number'
// JavaScript it('should provide a myNumber property', function () { expect(typeof scope.ctrl.myNumber).toBe('number'); });
#####attach myObject to the scope ↑
# CoffeeScript it 'should provide a myObject property', -> expect(scope.ctrl.myObject instanceof Object).toBe true
// JavaScript it('should provide a myObject property', function () { expect(scope.ctrl.myObject instanceof Object).toBe(true); });
#####attach myRegExp to the scope ↑
# CoffeeScript it 'should provide a myRegExp property', -> expect(scope.ctrl.myRegExp instanceof RegExp).toBe true
// JavaScript it('should provide a myRegExp property', function () { expect(scope.ctrl.myRegExp instanceof RegExp).toBe(true); });
#####attach myString to the scope ↑
# CoffeeScript it 'should provide a myString property', -> expect(typeof scope.ctrl.myString).toBe 'string'
// JavaScript it('should provide a myString property', function () { expect(typeof scope.ctrl.myString).toBe('string'); });
#####expect myUndefined to be undefined ↑
# CoffeeScript it 'should expect myUndefined to be undefined', -> expect(scope.ctrl.myUndefined).not.toBeDefined()
// JavaScript it('should expect myUndefined to be undefined', function () { expect(scope.ctrl.myUndefined).not.toBeDefined(); });
#####myMethod should return expected value ↑
# CoffeeScript it 'myMethod should return expected value', -> result = scope.ctrl.myMethod() expect(result).toBe('Not implemented')
// JavaScript it('myMethod should return expected value', function () { var result = scope.ctrl.myMethod(); expect(result).toBe('Not implemented'); });
#####call myMethod2 on myCtrl ↑
Use to make sure one method is calling another.
# CoffeeScript it 'should call myMethod2 from myMethod', -> # PULL REQUEST WELCOME!
// JavaScript it('should call myMethod2 from myMethod', function () { // PULL REQUEST WELCOME! });
#####call myMethod on mySvc ↑
# CoffeeScript it 'should call myMethod on mySvc', -> expect(mySvc.myMethod.callCount).toBe 1 expect(mySvc.myMethod).toHaveBeenCalledWith jasmine.any(Object)
// JavaScript it('should call myMethod on mySvc', function () { expect(mySvc.myMethod.callCount).toBe(1); expect(mySvc.myMethod).toHaveBeenCalledWith(jasmine.any(Object)); });