Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test John papa vm.model unit testing with jasmine?

I use John papa angular style guide my controller looks like:

following the style John papa style controller style guide:

function testController() {

    var vm = this;

    vm.model = { name: "controllerAs vm test" };
}

My testing code looks like:

describe('Controller: testController', function () {

    beforeEach(module('myApp'));

    var testController;

    beforeEach(inject(function ($controller) {
        scope = {};

        testController = $controller('testController', {
        });

    }));

    it('should have vm.model defined and testController.vm.model is equal to controllerAs vm test', function () { 
        expect(testController.vm).toBeDefined();  
        expect(testController.vm.model).toBeDefined();     
        expect(testController.vm.model.name).toEqual("controllerAs vm test");
    });
});

Result:

Test failed: Result Message: Expected undefined to be defined. at stack

So my question is how can we test vm.model and other variables from this? I have not found proper guide line in the guide lines: controllers

like image 560
Utpal Kumar Das Avatar asked Feb 11 '15 14:02

Utpal Kumar Das


2 Answers

The vm is equal to the instance itself via vm = this;

Therefore, all the properties are hanging directly off of the object.

function foo(){
  var vm = this;

  vm.name = 'Josh';
}

var myFoo = new foo();
myFoo.name; // 'Josh';

So all you need to do is change your expectations to remove the vm property.

expect(testController).toBeDefined();  
expect(testController.model).toBeDefined();     
expect(testController.model.name).toEqual("controllerAs vm test");

In order to prove this, here is your exact example, and the associated Jasmine tests.

function testController() {

  var vm = this;

  vm.model = {
    name: "controllerAs vm test"
  };
}


angular.module('myApp', [])
  .controller('testController', testController);

describe('Controller: testController', function() {

  beforeEach(module('myApp'));

  var testController;

  beforeEach(inject(function($controller) {
    scope = {};

    testController = $controller('testController', {});

  }));

  it('should have model defined and testController.model.name is equal to controllerAs vm test', function() {
    expect(testController).toBeDefined();
    expect(testController.model).toBeDefined();
    expect(testController.model.name).toEqual("controllerAs vm test");
  });

  it('should not have a property called vm', function() {
    expect(testController.vm).toBeUndefined();
  });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular-mocks.js"></script>
like image 57
Josh Avatar answered Oct 27 '22 18:10

Josh


testController is the vm because you set var vm = this in the controller. So, to make your test code more similar to your controller code, you can try to set your controller to vm in the test too instead of testController

describe('Controller: testController', function () {
    // we work with "vm" instead of "testController" to have consistent verbiage
    // in test and controller
    var vm;

    beforeEach(module('app'));
    beforeEach(inject(function ($controller) {
        vm = $controller('testController', {}, {});
    }));

    it('should have vm.model defined and testController.vm.model is equal to controllerAs vm test', function () {

        // vm=this in controller
        expect(vm)
            .toBeDefined();

        // Testing primitives
        expect(vm.foo)
            .toBeDefined();
        expect(vm.foo)
            .toEqual('bar');

        // Testing objects
        expect(vm.model)
            .toBeDefined();
        expect(vm.model.name)
            .toEqual("Batman");

        // Testing a method
        expect(vm.greet())
            .toBeDefined();
        expect(vm.greet())
            .toEqual('Hello There');
    });
});

Code for the controller

(function () {
    'use strict';

    angular
        .module('app')
        .controller('testController', testController);

    /* @ngInject */
    function testController() {
        var vm = this;

        // Primitives
        vm.foo = 'bar';

        // Objects
        vm.model = {
            name: 'Batman'
        };

        // Methods
        vm.greet = function () {
            return 'Hello There';
        };
    }
})();

Hope this helps. Good Luck.

like image 45
Aakash Avatar answered Oct 27 '22 20:10

Aakash