Ian McNally

bindToController in tests

March 26, 2015

In an Angular directive, you can use the bindToController property to set your $scope injections on the controller instance. It all works great, but things get murky when it comes to testing.

If you want to pass in mock data in a directive controller during a test, you have to modify how you instantiate the controller. It turns out a third argument to $controller is boolean called later that’ll return a function.

On that function’s instance property, you can add your mock injections. Then when you invoke the function, you’ll get the controller instance with your mocks attached.

A quick example:


angular.module('todoapp', [])
.directive('todoList', function(){
  scope: {
    items: '='
  bindToController: true
  controller: 'Todo'
.controller('Todo', function(){
  var controller = this;

  controller.amountOfTodos = function(){
    return controller.items.length;


describe('getAmountOfTodos', function(){
    var controller = $controller('Todo', {}, true);
    angular.extend(controller.instance, {
      items: [
          'Take out laundry'
    controller = controller();

    it('returns the count of todo items', function(){

Props. and open issue.

Ian McNally

Hey, I'm Ian. I build websites and write about what I learn as I go. Follow me on Twitter.