Using Angular decorators for testing
As seen in the blogpost!
by Alberto Pose
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.js"></script>
<script src="http://code.angularjs.org/1.1.5/angular.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.css">
<script src="http://chaijs.com/chai.js"></script>
<!-- We are going to use Mocha + Chai setup for testing -->
<script>
mocha.setup('tdd');
chai.should();
</script>
<body>
<div id="mocha"></div>
</body>
<!-- Adding angular mocks to have 'module' and 'inject' functions -->
<script src="http://code.angularjs.org/1.1.5/angular-mocks.js"></script>
JavaScript
/*
# Using decorators for unit testing
The idea behind this simple app is to show how to use Decorators in Angular to do unit testing.
In this case we have two factories: One called parent and the other child. What we want to achieve is write unit tests for the child factory instance.
Here is a simple Angular module that contains both parent and child:
*/
angular.module('myApp', [])
.factory('greeter', function () {
return 'Hello';
})
.factory('worldGreeter', function (greeter) {
return greeter + ' World';
});
/* As you can see, child is concatenating the input from parent.
So let's write some tests using mocha:
*/
describe('worldGreeter', function () {
var worldGreeter;
/* We are including myApp module for testing */
beforeEach(module('myApp'));
/* We are replacing parent with our own implementation.
$delegate is a reference to the old parent instance. $delegate
is really helpful if you plan mocking or stubbing it using a framework
like sinon. */
beforeEach(module(function ($provide) {
$provide.decorator('greeter', function ($delegate) {
return 'Bye';
});
}));
/* Here we have another angular trick, we name the instance _child_
so we can have a variable named child on the describe scope. inject recognizes
this and injects the proper instance allowing the usage of the more handy child
variable. */
beforeEach(inject(function (_worldGreeter_) {
worldGreeter = _worldGreeter_;
}));
/* Finally, we can see the assertion that parent was
replaced successfully */
it('should work with mocked greeter', function (done) {
worldGreeter.should.be.equal('Bye World');
done();
});
});
mocha.run();
/* To sum up, great things can be achieved with decorator in what test is related. Although
there is little documentation on that feature, it is really useful when having to replace an instance dependencies. */