SlideShare a Scribd company logo
ng-conf 2014 Israel
big thanks to our sponsors:
How { Testability } Inspires
AngularJS Design
Ran Mizrahi (@ranm8)

Founder and CEO @ CoCycles
About { Me }
• Founder and CEO of CoCycles.

• Former Open Source Dpt. Leader of CodeOasis.

• Architected and managed the Wix App Market Development.

• Full-stack and hands-on software engineer.

What is { Testability } ?
“AngularJS - Web Framework Designed
with { Testability } in Mind “
How many times have you heard that?
What is { Testability } ?
Why is { Testability } so
important???
What is { Testability } ?
“Software testability is the degree to
which a software artifact supports testing
in a given test context”
— Wikipedia
What is { Testability } ?
Can I maintain tests? Can I test the code?
• Unmaintainable tests
makes code untestable.

• Broken tests that now one
never bothers to fix

• One tiny change - many
tests break (inc. unrelated
ones)
• Lots of untested code /
poor code coverage

• Monkey patching.

{ Global } State
function foo() {
var bar = window.bar;
!
if (bar) {
return null;
}
!
return bar;
}
Testing global states is difficult and forces “monkey
patching” (which is not applicable in all languages)…
function foo(bar) {
!
!
if (bar) {
return null;
}
!
return bar;
}
Use of global state: Injecting the dependency:
{ Global } State
“Insanity: doing the same thing over and over
again and expecting different results.”
— Einstien
{ Global } State
describe('foo', function() {
// global
it('should return null since `window.bar` is falsy', function() {
window.bar = false;
expect(foo()).to.be.null;
});
//injected
it('should return bar since window.bar is truthy', function() {
expect(foo(‘hi’)).to.be(‘hi');
});
});
Avoiding global state makes our code more:



• Reliable

• Polymorphic

• Decoupled
{ Coupling } Units
function doSomethingWithBar(bar) {
return bar.doSomething();
}
!
doSomethingWithBar(new Bar());
doSomethingWithBar(new WalkingBar());
function doSomethingWithBar() {
var bar = new Bar();
return bar.doSomething();
}
Coupled unit:
Decoupled unit:
• Coupled to specific
implementation.

• Can be tested only with
monkey patching.

• (Almost ) Impossible to
test with complicated
implementations.
• Decoupled from specific
implementation.

• Can be easily tested
(replaced with a mock).
{ Coupling } Units
describe('#doSomethingWithBar()', function() {
var bar;
beforeEach(function() {
bar = {
doSomething: sinon.stub().returns('something')
};
});
it('should call bar.doSomething and return', function() {
var result = doSomethingWithBar(bar);
expect(result).to.equal('something');
expect(bar.doSomething).to.have.been.called;
});
});
And it’s much easier to test (no need to handle the new
operator in our tests)
Code { Complexity }
function kill(bill) {
if (bill.talker() != null) {
bill.talk();
return "Bill talked";
}
!
if (bill.isDead()) {
bill.resurrect();
!
return "Bill Resurrected";
}
!
if (bill.isAlive()) {
bill.kill();
!
return "Bill is now dead";
}
!
if (bill.isCool()) {
bill.cool();
!
return "Bill is now cool";
}
!
return "Nothing happened";
}
• This code has five different
possible outcomes.

!
• Hard to predict, debug and
maintain.

!
• Testing it requires lots of code.

• No one else but you, would
dare to maintain this test (-:

• Bad separation of concerns.

• For desert, we need only five
different version of mocks.
Code { Complexity }
!
describe('kill', function() {
var bill;
!
beforeEach(function() {
bill = {
talker: sinon.stub(),
isDead: sinon.stub(),
isAlive: sinon.stub()
isCool: sinon.stub()
};
});
it('should make bill talk', function() {
bill.talker.returns(true);
!
expect(kill(bill)).to.equal('Bill talked');
});
!
it('should resurrect bill', function() {
bill.isDead.returns(true);
expect(kill(bill)).to.equal('Bill Resurrected');
});
!
it('should kill bill', function() {
bill.isAlive(true);
!
expect(kill(bill)).to.equal('Bill is now dead');
});
!
it('should notice that nothing happened', function(){
expect(kill(bill)).to.equal('Nothing happened');
});
!
it('should make bill extremely cool', function() {
bill.isCool(true);
!
expect(kill(bill)).to.equal('Bill is now cool');
});
});
Sorry it’s small, but
it makes my point
(-:
Object { Dependencies }
function foo(bar, boo, bla, beer) {
function doComplicatedStuff() {
return bla.sayHi() + boo.sayPizza() + bla.sayBla() + beer.drink();
}
return {
getSome: function() {
return doComplicatedStuff();
}
};
}
• Many dependencies === Too many responsibilities.

• Too much mocks to maintain.

• Bad separation of concerns.
Object { Dependencies }
describe('foo', function() {
var boo = {},
bar = {},
bla = {},
beer = {};
beforeEach(function() {
bla.sayHi = sinon.stub().returns('hi ');
boo.sayPizza = sinon.stub().returns('pizza ');
bla.sayBla = sinon.stub().returns('bla ');
beek.drink = sinon.stub().returns('glagla ');
});
describe('#getSome()', function() {
it('should call all dependencies explicitly and returns and concatenated
string', function() {
var foo = foo(bar, boo, bla, beer);
expect(foo.getSome()).to.equal('hi pizza bla glagla');
});
});
});
• The more dependencies, the harder to test.

• Too much mocks to maintain.
Other { Signs }
Other signs that makes code untestable:

!
• Constructor does heavy work.

• Object are passed but never used directly.

• Singletons.

• Unit do too much jobs.

• Side effects
{ Testability } is Good!
Testability === Code Quality
Polymorphic
Encapsulated
Decoupled
{ Maintainable } and { Predictable } Code
{ Testability } in AngularJS
So, What Makes AngularJS
{ Testable} ???
{ Angular’s } Approach
• Angular approach is declarative and not imperative.

• Separates controller-logic from DOM using directives and
data binding.

• Less code === less to test.
{ Dependency } Injection
• Angular inject the requested service by the function argument
names (declarative approach).

• Can also be done with an array.

!
• Once requested Angular’s injector would instantiate the
requested service and inject it.
angular.module('myModule')
.controller('MyCtrl', MyCtrl);
function MyCtrl($http) {
$http.get('http://google.com').then(getTheMonkey);
}
{ Dependency } Injection
• Allows minifiers to preserve argument names for the
dependency injection to work with. 

• More flexible - Separates dependency declaration from your
unit.
angular.module('myModule')
.controller('MyCtrl', ['$http', MyCtrl]);
function MyCtrl($http) {
$http.get('http://google.com').then(getTheMonkey);
}
DOM - Controller { Separation }
angular.module('myModule')
.controller('MyCtrl', ['$scope', MyCtrl]);
function MyCtrl($scope) {
$scope.array = ['one', 'two', 'three'];
$scope.addAnotherOne = function(string) {
$scope.array.push(string);
}
$scope.removeFirst = function() {
$scope.array.shift();
}
}
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="property in array">{{ property }}</li>
</ul>
<a ng-click="removeFirst()">Remove the first property<a>
</div>
DOM - Controller { Separation }
• Two-way data-binding leaves your controller clean from DOM
manipulation and makes it easier to test. 

• Less code.

• Decouples the view from the controller.

!
!
describe('MyCtrl', function() {
var createController,
scope;
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
createController = function() {
return $controller('MainCtrl', {
$scope: scope
})
}
}));
it('should remove one property from the array', function() {
var controller = createController();
// test your controller
});
});
{ Directives }
• Directives handles the responsibility of DOM
manipulation.

• They separate the DOM from your code by avoiding the
use of CSS selectors.

• Easy to reuse across different applications and contexts.
app.directive('sampleOne', function (){
return function(scope, elm, attrs) {
elm.bind('click', function(){
elm.text(scope.$eval(attrs.sampleOne));
});
};
});
{ Directives }
describe('Testing sampleOne directive', function() {
var scope,
elem,
directive,
compiled,
html;
beforeEach(function (){
html = '<div sample-one="foo"></div>';
inject(function($compile, $rootScope) {
scope = $rootScope.$new();
elm = angular.element(html);
compiled = $compile(elm)(scope);
scope.$digest();
});
});
!
it('Should set the text of the element to whatever was passed.', function() {
scope.foo = 'bar';
expect(elem.text()).toBe('');
elm[0].click();
expect(elem.text()).toBe('bar');
});
});
{ Providers/Services/Factories }
• Providers allows you to separate configuration phase from
run phase.

• Separate your code to small and reusable units.

• Providers can be easily isolated and tested.
angular.module('myModule')
.provider('myHttp', myHttp);
function myHttp() {
var baseUrl;
this.baseUrl = function(value) {
if (!value) {
return baseUrl;
}
baseUrl = value;
};
this.$get = ['$q', function() {
// myHttp service implementation...
}];
}
Configuration Phase
Run Phase
• Runs before any service was instantiated.

!
• Only providers can be injected.

!
• Each provider is injected with the “Provider” suffix (e.g.
$locationProvider)

!
• Allows to purely configure the services state.

• Services state should be not be changed now (already
configured during run phase).

!
• Providers now cannot be injected.
{ Providers/Services/Factories }
Testing { Providers/Services/Factories }
describe('myHttp', function() {
!
var mockQ = {
then: function(){}
},
http;
beforeEach(module(function($provide) {
$provide.value('$q', mockQ);
}));
beforeEach(inject(function(myHttp) {
http = myHttp;
}));
describe('#get()', function() {
it('should return a promise', function() {
// test your code here
});
});
});
{ Wrappers }
angular.module('myModule')
.provider('someProvider', ['$window', someProvider]);
function someProvider($window, $) {
this.$get = function() {
$window.alert('hey there');
}
}
!
• Angular provides wrappers to common global objects.

• It allows to easily test global properties without having to
monkey patch the window object.

!
• Wrappers are injected with dependency injection.
Any { Questions } ?

More Related Content

PPTX
Angular Unit Testing
PDF
Client side unit tests - using jasmine & karma
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
PDF
How AngularJS Embraced Traditional Design Patterns
PPTX
Angular Unit Testing
PDF
Angular testing
PDF
Angular Application Testing
PPTX
Unit testing JavaScript: Jasmine & karma intro
Angular Unit Testing
Client side unit tests - using jasmine & karma
Intro To JavaScript Unit Testing - Ran Mizrahi
How AngularJS Embraced Traditional Design Patterns
Angular Unit Testing
Angular testing
Angular Application Testing
Unit testing JavaScript: Jasmine & karma intro

What's hot (20)

PDF
Testing most things in JavaScript - LeedsJS 31/05/2017
PDF
Angular Unit Testing NDC Minn 2018
PDF
Angular Unit Testing from the Trenches
PDF
Painless JavaScript Testing with Jest
PDF
Intro to Unit Testing in AngularJS
PDF
Unit Testing JavaScript Applications
PDF
Automated Testing in Angular Slides
PDF
Intro to JavaScript Testing
PPTX
Unit testing of java script and angularjs application using Karma Jasmine Fra...
ODP
Angular JS Unit Testing - Overview
PPTX
Unit testing in JavaScript with Jasmine and Karma
PPTX
Testing React Applications
ODP
Unit Testing and Coverage for AngularJS
PDF
AngularJS Unit Testing w/Karma and Jasmine
PDF
Intro to testing Javascript with jasmine
PDF
Angularjs - Unit testing introduction
PPT
Testing in AngularJS
PDF
Test-Driven Development of AngularJS Applications
PDF
Quick tour to front end unit testing using jasmine
PDF
Exploring Angular 2 - Episode 2
Testing most things in JavaScript - LeedsJS 31/05/2017
Angular Unit Testing NDC Minn 2018
Angular Unit Testing from the Trenches
Painless JavaScript Testing with Jest
Intro to Unit Testing in AngularJS
Unit Testing JavaScript Applications
Automated Testing in Angular Slides
Intro to JavaScript Testing
Unit testing of java script and angularjs application using Karma Jasmine Fra...
Angular JS Unit Testing - Overview
Unit testing in JavaScript with Jasmine and Karma
Testing React Applications
Unit Testing and Coverage for AngularJS
AngularJS Unit Testing w/Karma and Jasmine
Intro to testing Javascript with jasmine
Angularjs - Unit testing introduction
Testing in AngularJS
Test-Driven Development of AngularJS Applications
Quick tour to front end unit testing using jasmine
Exploring Angular 2 - Episode 2
Ad

Viewers also liked (20)

PPT
PDF
3. sxeseis kai omada sto didaktiko sxedio
PPT
00 are you free - taxis
PPT
Arts1510 fall 2012 - requirements
PDF
Cisco_Services_dynamics_magazine_issue_5-2012
PPT
παρουσίαση 2 ιδεοκατασκευών έκδοση 1
PPTX
Brazilian protests – June 2013
PPT
Towns In Macedonia
PDF
The Mundanity of Excellence: An Ethnographic Report on Stratification and Oly...
PPT
Jornada de motivacion y busqueda de opciones
PPT
Towns In Macedonia
PPS
Euskara motibazioak
PDF
SpringOwl Yahoo! Investor Presentation
KEY
Product Managers and Startups
PPT
Planning Value Measurements into your Social Media Strategy
PDF
PPSX
γιορτινές ευχές 2015
PPTX
ανακύκλωση 2014
3. sxeseis kai omada sto didaktiko sxedio
00 are you free - taxis
Arts1510 fall 2012 - requirements
Cisco_Services_dynamics_magazine_issue_5-2012
παρουσίαση 2 ιδεοκατασκευών έκδοση 1
Brazilian protests – June 2013
Towns In Macedonia
The Mundanity of Excellence: An Ethnographic Report on Stratification and Oly...
Jornada de motivacion y busqueda de opciones
Towns In Macedonia
Euskara motibazioak
SpringOwl Yahoo! Investor Presentation
Product Managers and Startups
Planning Value Measurements into your Social Media Strategy
γιορτινές ευχές 2015
ανακύκλωση 2014
Ad

Similar to How Testability Inspires AngularJS Design / Ran Mizrahi (20)

PDF
Automated acceptance test
PDF
Intro to node.js - Ran Mizrahi (27/8/2014)
PDF
Intro to node.js - Ran Mizrahi (28/8/14)
PPTX
Web technologies-course 12.pptx
PDF
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
PDF
Angular for Java Enterprise Developers: Oracle Code One 2018
PDF
Quick tour to front end unit testing using jasmine
PPTX
Javascript first-class citizenery
PDF
Angularjs Test Driven Development (TDD)
PDF
AngularJS - TechTalk 3/2/2014
PPTX
OpenDaylight Developer Experience 2.0
PDF
Angular or Backbone: Go Mobile!
PPT
Coffee@DBG - Exploring Angular JS
PPTX
Java script unit testing
PPTX
Angular from a Different Angle
PDF
Javascript tdd byandreapaciolla
PDF
Ionic framework one day training
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
PDF
Javascript-heavy Salesforce Applications
PPTX
Good karma: UX Patterns and Unit Testing in Angular with Karma
Automated acceptance test
Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (28/8/14)
Web technologies-course 12.pptx
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Angular for Java Enterprise Developers: Oracle Code One 2018
Quick tour to front end unit testing using jasmine
Javascript first-class citizenery
Angularjs Test Driven Development (TDD)
AngularJS - TechTalk 3/2/2014
OpenDaylight Developer Experience 2.0
Angular or Backbone: Go Mobile!
Coffee@DBG - Exploring Angular JS
Java script unit testing
Angular from a Different Angle
Javascript tdd byandreapaciolla
Ionic framework one day training
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Javascript-heavy Salesforce Applications
Good karma: UX Patterns and Unit Testing in Angular with Karma

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
Teaching material agriculture food technology
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Encapsulation theory and applications.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Electronic commerce courselecture one. Pdf
PPTX
Cloud computing and distributed systems.
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
The Rise and Fall of 3GPP – Time for a Sabbatical?
Network Security Unit 5.pdf for BCA BBA.
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Teaching material agriculture food technology
The AUB Centre for AI in Media Proposal.docx
Big Data Technologies - Introduction.pptx
Building Integrated photovoltaic BIPV_UPV.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Encapsulation theory and applications.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Review of recent advances in non-invasive hemoglobin estimation
Unlocking AI with Model Context Protocol (MCP)
Electronic commerce courselecture one. Pdf
Cloud computing and distributed systems.
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
“AI and Expert System Decision Support & Business Intelligence Systems”
Programs and apps: productivity, graphics, security and other tools
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Understanding_Digital_Forensics_Presentation.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows

How Testability Inspires AngularJS Design / Ran Mizrahi

  • 1. ng-conf 2014 Israel big thanks to our sponsors:
  • 2. How { Testability } Inspires AngularJS Design Ran Mizrahi (@ranm8) Founder and CEO @ CoCycles
  • 3. About { Me } • Founder and CEO of CoCycles.
 • Former Open Source Dpt. Leader of CodeOasis.
 • Architected and managed the Wix App Market Development.
 • Full-stack and hands-on software engineer.

  • 4. What is { Testability } ? “AngularJS - Web Framework Designed with { Testability } in Mind “ How many times have you heard that?
  • 5. What is { Testability } ? Why is { Testability } so important???
  • 6. What is { Testability } ? “Software testability is the degree to which a software artifact supports testing in a given test context” — Wikipedia
  • 7. What is { Testability } ? Can I maintain tests? Can I test the code? • Unmaintainable tests makes code untestable.
 • Broken tests that now one never bothers to fix
 • One tiny change - many tests break (inc. unrelated ones) • Lots of untested code / poor code coverage
 • Monkey patching.

  • 8. { Global } State function foo() { var bar = window.bar; ! if (bar) { return null; } ! return bar; } Testing global states is difficult and forces “monkey patching” (which is not applicable in all languages)… function foo(bar) { ! ! if (bar) { return null; } ! return bar; } Use of global state: Injecting the dependency:
  • 9. { Global } State “Insanity: doing the same thing over and over again and expecting different results.” — Einstien
  • 10. { Global } State describe('foo', function() { // global it('should return null since `window.bar` is falsy', function() { window.bar = false; expect(foo()).to.be.null; }); //injected it('should return bar since window.bar is truthy', function() { expect(foo(‘hi’)).to.be(‘hi'); }); }); Avoiding global state makes our code more: • Reliable • Polymorphic • Decoupled
  • 11. { Coupling } Units function doSomethingWithBar(bar) { return bar.doSomething(); } ! doSomethingWithBar(new Bar()); doSomethingWithBar(new WalkingBar()); function doSomethingWithBar() { var bar = new Bar(); return bar.doSomething(); } Coupled unit: Decoupled unit: • Coupled to specific implementation. • Can be tested only with monkey patching. • (Almost ) Impossible to test with complicated implementations. • Decoupled from specific implementation. • Can be easily tested (replaced with a mock).
  • 12. { Coupling } Units describe('#doSomethingWithBar()', function() { var bar; beforeEach(function() { bar = { doSomething: sinon.stub().returns('something') }; }); it('should call bar.doSomething and return', function() { var result = doSomethingWithBar(bar); expect(result).to.equal('something'); expect(bar.doSomething).to.have.been.called; }); }); And it’s much easier to test (no need to handle the new operator in our tests)
  • 13. Code { Complexity } function kill(bill) { if (bill.talker() != null) { bill.talk(); return "Bill talked"; } ! if (bill.isDead()) { bill.resurrect(); ! return "Bill Resurrected"; } ! if (bill.isAlive()) { bill.kill(); ! return "Bill is now dead"; } ! if (bill.isCool()) { bill.cool(); ! return "Bill is now cool"; } ! return "Nothing happened"; } • This code has five different possible outcomes. ! • Hard to predict, debug and maintain. ! • Testing it requires lots of code.
 • No one else but you, would dare to maintain this test (-:
 • Bad separation of concerns.
 • For desert, we need only five different version of mocks.
  • 14. Code { Complexity } ! describe('kill', function() { var bill; ! beforeEach(function() { bill = { talker: sinon.stub(), isDead: sinon.stub(), isAlive: sinon.stub() isCool: sinon.stub() }; }); it('should make bill talk', function() { bill.talker.returns(true); ! expect(kill(bill)).to.equal('Bill talked'); }); ! it('should resurrect bill', function() { bill.isDead.returns(true); expect(kill(bill)).to.equal('Bill Resurrected'); }); ! it('should kill bill', function() { bill.isAlive(true); ! expect(kill(bill)).to.equal('Bill is now dead'); }); ! it('should notice that nothing happened', function(){ expect(kill(bill)).to.equal('Nothing happened'); }); ! it('should make bill extremely cool', function() { bill.isCool(true); ! expect(kill(bill)).to.equal('Bill is now cool'); }); }); Sorry it’s small, but it makes my point (-:
  • 15. Object { Dependencies } function foo(bar, boo, bla, beer) { function doComplicatedStuff() { return bla.sayHi() + boo.sayPizza() + bla.sayBla() + beer.drink(); } return { getSome: function() { return doComplicatedStuff(); } }; } • Many dependencies === Too many responsibilities. • Too much mocks to maintain. • Bad separation of concerns.
  • 16. Object { Dependencies } describe('foo', function() { var boo = {}, bar = {}, bla = {}, beer = {}; beforeEach(function() { bla.sayHi = sinon.stub().returns('hi '); boo.sayPizza = sinon.stub().returns('pizza '); bla.sayBla = sinon.stub().returns('bla '); beek.drink = sinon.stub().returns('glagla '); }); describe('#getSome()', function() { it('should call all dependencies explicitly and returns and concatenated string', function() { var foo = foo(bar, boo, bla, beer); expect(foo.getSome()).to.equal('hi pizza bla glagla'); }); }); }); • The more dependencies, the harder to test. • Too much mocks to maintain.
  • 17. Other { Signs } Other signs that makes code untestable: ! • Constructor does heavy work.
 • Object are passed but never used directly.
 • Singletons.
 • Unit do too much jobs.
 • Side effects
  • 18. { Testability } is Good! Testability === Code Quality Polymorphic Encapsulated Decoupled { Maintainable } and { Predictable } Code
  • 19. { Testability } in AngularJS So, What Makes AngularJS { Testable} ???
  • 20. { Angular’s } Approach • Angular approach is declarative and not imperative.
 • Separates controller-logic from DOM using directives and data binding.
 • Less code === less to test.
  • 21. { Dependency } Injection • Angular inject the requested service by the function argument names (declarative approach).
 • Can also be done with an array. ! • Once requested Angular’s injector would instantiate the requested service and inject it. angular.module('myModule') .controller('MyCtrl', MyCtrl); function MyCtrl($http) { $http.get('http://google.com').then(getTheMonkey); }
  • 22. { Dependency } Injection • Allows minifiers to preserve argument names for the dependency injection to work with. 
 • More flexible - Separates dependency declaration from your unit. angular.module('myModule') .controller('MyCtrl', ['$http', MyCtrl]); function MyCtrl($http) { $http.get('http://google.com').then(getTheMonkey); }
  • 23. DOM - Controller { Separation } angular.module('myModule') .controller('MyCtrl', ['$scope', MyCtrl]); function MyCtrl($scope) { $scope.array = ['one', 'two', 'three']; $scope.addAnotherOne = function(string) { $scope.array.push(string); } $scope.removeFirst = function() { $scope.array.shift(); } } <div ng-controller="MyCtrl"> <ul> <li ng-repeat="property in array">{{ property }}</li> </ul> <a ng-click="removeFirst()">Remove the first property<a> </div>
  • 24. DOM - Controller { Separation } • Two-way data-binding leaves your controller clean from DOM manipulation and makes it easier to test. 
 • Less code.
 • Decouples the view from the controller. ! ! describe('MyCtrl', function() { var createController, scope; beforeEach(inject(function($rootScope, $controller) { scope = $rootScope.$new(); createController = function() { return $controller('MainCtrl', { $scope: scope }) } })); it('should remove one property from the array', function() { var controller = createController(); // test your controller }); });
  • 25. { Directives } • Directives handles the responsibility of DOM manipulation.
 • They separate the DOM from your code by avoiding the use of CSS selectors.
 • Easy to reuse across different applications and contexts. app.directive('sampleOne', function (){ return function(scope, elm, attrs) { elm.bind('click', function(){ elm.text(scope.$eval(attrs.sampleOne)); }); }; });
  • 26. { Directives } describe('Testing sampleOne directive', function() { var scope, elem, directive, compiled, html; beforeEach(function (){ html = '<div sample-one="foo"></div>'; inject(function($compile, $rootScope) { scope = $rootScope.$new(); elm = angular.element(html); compiled = $compile(elm)(scope); scope.$digest(); }); }); ! it('Should set the text of the element to whatever was passed.', function() { scope.foo = 'bar'; expect(elem.text()).toBe(''); elm[0].click(); expect(elem.text()).toBe('bar'); }); });
  • 27. { Providers/Services/Factories } • Providers allows you to separate configuration phase from run phase.
 • Separate your code to small and reusable units.
 • Providers can be easily isolated and tested. angular.module('myModule') .provider('myHttp', myHttp); function myHttp() { var baseUrl; this.baseUrl = function(value) { if (!value) { return baseUrl; } baseUrl = value; }; this.$get = ['$q', function() { // myHttp service implementation... }]; }
  • 28. Configuration Phase Run Phase • Runs before any service was instantiated. ! • Only providers can be injected. ! • Each provider is injected with the “Provider” suffix (e.g. $locationProvider) ! • Allows to purely configure the services state. • Services state should be not be changed now (already configured during run phase). ! • Providers now cannot be injected. { Providers/Services/Factories }
  • 29. Testing { Providers/Services/Factories } describe('myHttp', function() { ! var mockQ = { then: function(){} }, http; beforeEach(module(function($provide) { $provide.value('$q', mockQ); })); beforeEach(inject(function(myHttp) { http = myHttp; })); describe('#get()', function() { it('should return a promise', function() { // test your code here }); }); });
  • 30. { Wrappers } angular.module('myModule') .provider('someProvider', ['$window', someProvider]); function someProvider($window, $) { this.$get = function() { $window.alert('hey there'); } } ! • Angular provides wrappers to common global objects.
 • It allows to easily test global properties without having to monkey patch the window object. ! • Wrappers are injected with dependency injection.