StackOverflow_21218273: how-to-inject-a-controller-into-a-directive-when-unit-testing

Illustration of answer to http://stackoverflow.com/questions/21218273/how-to-inject-a-controller-into-a-directive-when-unit-testing.

by ExpertSystem

HTML

<script src="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.9/angular-mocks.js"></script>
<link rel="stylesheet" href="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<pre ng-app="myApp" ng-controller="myCtrl">
    <b>With real controller</b>: <span hello></span>
    <b>With mock controller</b>: <span id="testOutput"></span>
</pre>

JavaScript

var app = angular.module('myApp', []);
app.factory('Greeting', function () {
    return { salutation: 'Hello' };
});
app.controller('myCtrl', function ($scope) {
    $scope.model = {
        salutation: 'Welcome',
        user: 'world'
    };
});
app.controller('dirCtrl', function ($scope, Greeting) {
    $scope.model = {
        salutation: Greeting.salutation,
        user: 'ExpertSystem'
    };
});
app.directive('hello', function () {
    return {
        template: '<span>{{model.salutation}}, {{model.user}} !</span>',
        controller: 'dirCtrl'
    };
});

describe('Hello Directive', function () {
    var $compile;
    var $newScope;
    var testSpan;
    
    angular.module('testApp', ['myApp'])
    .controller('dirCtrl', function ($scope, Greeting) {
        $scope.model = {
            salutation: Greeting.salutation,
            user: 'Tester'
        };
    });
    
    beforeEach(function () {
        module('testApp');
        inject(function (_$compile_, $rootScope) {
            $compile = _$compile_;
            $newScope = $rootScope.$new();
            testSpan = document.body.querySelector('#testOutput');
        });
    });
    
    it('should greet the tester', function () {
        var elem = angular.element('<span hello></span>');
        $compile(elem)($newScope);
        angular.element(testSpan).replaceWith(elem);
        $newScope.$digest();
        expect(elem.text()).toEqual('Hello, Tester !');
    });
});


(function() {
  var env = jasmine.getEnv();
  env.addReporter(new jasmine.HtmlReporter());
  env.execute();
}());