0

I am following the angularjs tutorial here : https://docs.angularjs.org/tutorial/step_02

My original controller:

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function ($scope) {
    $scope.phones = [
        {'name': 'Nexus S',
            'snippet': 'Fast just got faster with Nexus S.'},
        {'name': 'Motorola XOOM™ with Wi-Fi',
            'snippet': 'The Next, Next Generation tablet.'},
        {'name': 'MOTOROLA XOOM™',
            'snippet': 'The Next, Next Generation tablet.'}
    ];
});

original test:

'use strict';

/* jasmine specs for controllers go here */

describe('PhoneListCtrl', function () {

    beforeEach(module('phonecatApp'));

    it("should create 'phones' model with 3 phones", inject(function ($controller) {
        var scope = {},
            ctrl = $controller('PhoneListCtrl', {$scope: scope});

        expect(scope.phones.length).toBe(3);


    }));

});

New controller (using the 'this' way of things)

Angular: Should I use this or $scope

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function () {
    this.phones = [
        {
            'name': 'Nexus S',
            'snippet': 'Fast just got faster with Nexus S.'
        },
        {
            'name': 'Motorola XOOM™ with Wi-Fi',
            'snippet': 'The Next, Next Generation tablet.'
        },
        {
            'name': 'MOTOROLA XOOM™',
            'snippet': 'The Next, Next Generation tablet.'
        }
    ];
});

How should the test change to make things work?

Currently I see the following error

Chrome 41.0.2272 (Mac OS X 10.10.2) PhoneListCtrl should create 'phones' model with 3 phones FAILED
    TypeError: Cannot read property 'length' of undefined
        at null.<anonymous> (/Users/somghosh/Programming/angular-phonecat/test/unit/controllersSpec.js:13:32)
        at Object.invoke (/Users/somghosh/Programming/angular-phonecat/app/bower_components/angular/angular.js:4185:17)
        at workFn (/Users/somghosh/Programming/angular-phonecat/app/bower_components/angular-mocks/angular-mocks.js:2364:20)
    Error: Declaration Location
        at window.inject.angular.mock.inject (/Users/somghosh/Programming/angular-phonecat/app/bower_components/angular-mocks/angular-mocks.js:2335:25)
        at null.<anonymous> (/Users/somghosh/Programming/angular-phonecat/test/unit/controllersSpec.js:9:58)
        at /Users/somghosh/Programming/angular-phonecat/test/unit/controllersSpec.js:5:5
Chrome 41.0.2272 (Mac OS X 10.10.2): Executed 1 of 1 (1 FAILED) ERROR (0.009 secs / 0.009 secs)
Community
  • 1
  • 1
dowjones123
  • 3,695
  • 5
  • 40
  • 83

1 Answers1

0

When you place phones as a property of your controller instance you need to test that, not the scope directly. So just use the controller instance returned by the $controller service and set you expectation against that.

it("should create 'phones' model with 3 phones", inject(function ($controller) {
        var ctrl = $controller('PhoneListCtrl');
        expect(ctrl.phones.length).toBe(3);
}));

Plnkr

PSL
  • 123,204
  • 21
  • 253
  • 243
  • At least that you wanna check if the controllerAs is attaching the expected attributes to the controller, if you are using the controllerAs i prefer check if the $scope['controllerAsName'] because in the template this is the real value – Jesús Quintana Mar 07 '15 at 02:06
  • @JesúsQuintana When you are testing a controller you just do not have to do that.. It is a unit test after all, just test the controller, leaving all the abstractions of `controller as` behind. What you get as a result of $controller is nothing but the same controller instance which is attached to the scope as alias. And `you wanna check if the controllerAs is attaching the expected attributes to the controller` You do not need to check that, that is covered as a part of angular tests right?, so you just worry about your controller, not how it is attached when using a cntrAs or not.. IMHO. – PSL Mar 07 '15 at 02:07
  • thanks @PSL, I noticed in your .js, the whole code is wrapped around : (function (angular) { } -- why is this required? – dowjones123 Mar 07 '15 at 12:07