如何测试John papa vm。使用jasmine进行单元测试?

时间:2022-08-24 21:47:03

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

我用John papa的角度样式指导我的控制器看起来像:

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

我的问题是如何测试vm。模型和其他变量?我在指南中没有找到合适的指南线:控制器

3 个解决方案

#1


28  

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

vm通过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.

因此,您所需要做的就是更改您的期望以删除vm属性。

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>

#2


8  

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

testController是vm,因为您在控制器中设置了var vm = this。因此,为了使您的测试代码更类似于您的控制器代码,您可以尝试在测试中将您的控制器设置为vm,而不是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.

希望这个有帮助。祝你好运。

#3


1  

I would create a new module and inject it as a dependency into the app module to make it simple and testable. Testing the controller with John Papa's Style Guide:

我将创建一个新的模块,并将它作为一个依赖项注入到app模块中,使其变得简单和可测试。用John Papa的风格指南测试控制器:

(function () {
  'use strict';

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

  function testController() {
    var vm = this;
    vm.model = { name: "controllerAs vm test" };
  }
})();

The spec now would look like this:

现在的规格是这样的:

'use strict';

describe('testController', function() {
  var testController;
  beforeEach(module('test'));

  beforeEach(function () {
    inject(function($injector) {
      testController = $injector.get('$controller')('testController', {});
    });
  });

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

Hope this helps anyone looking for similar solutions.

希望这对寻找类似解决方案的人有所帮助。

#1


28  

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

vm通过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.

因此,您所需要做的就是更改您的期望以删除vm属性。

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>

#2


8  

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

testController是vm,因为您在控制器中设置了var vm = this。因此,为了使您的测试代码更类似于您的控制器代码,您可以尝试在测试中将您的控制器设置为vm,而不是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.

希望这个有帮助。祝你好运。

#3


1  

I would create a new module and inject it as a dependency into the app module to make it simple and testable. Testing the controller with John Papa's Style Guide:

我将创建一个新的模块,并将它作为一个依赖项注入到app模块中,使其变得简单和可测试。用John Papa的风格指南测试控制器:

(function () {
  'use strict';

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

  function testController() {
    var vm = this;
    vm.model = { name: "controllerAs vm test" };
  }
})();

The spec now would look like this:

现在的规格是这样的:

'use strict';

describe('testController', function() {
  var testController;
  beforeEach(module('test'));

  beforeEach(function () {
    inject(function($injector) {
      testController = $injector.get('$controller')('testController', {});
    });
  });

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

Hope this helps anyone looking for similar solutions.

希望这对寻找类似解决方案的人有所帮助。