Angularjs 控制器测试中的单元测试状态参数

Angularjs 控制器测试中的单元测试状态参数,angularjs,unit-testing,jasmine,Angularjs,Unit Testing,Jasmine,我有一个使用$stateParams的基本控制器 angular.module('example') .controller('SampleCtrl', ['$stateParams', function($stateParams) { var vm = this; vm.isSomething = ($stateParams.isSomething === 'true') ? true : false; } ]); 在我的单

我有一个使用
$stateParams
的基本控制器

angular.module('example')
  .controller('SampleCtrl', ['$stateParams',
      function($stateParams) {
         var vm = this;
         vm.isSomething = ($stateParams.isSomething === 'true') ? true : false;
      }
  ]);
在我的单元测试中,我需要在一个测试中将
$stateParams.isSomething
设置为true,在另一个测试中设置为false

 describe('SampleCtrl Test', function() {

    var ctrl, scope, $stateParams;

    // set default stateParams
    $stateParams = { isSomething: 'false' };

    beforeEach(function(){
       inject(function($rootScope, $controller){
          scope = $rootScope.$new();

          ctrl = $controller('SampleCtrl', {
            $scope: scope,
            $stateParams: $stateParams
          });
       });
    });

    describe('when isSomething is false', function() {
         it('should be false', function() {
            expect(ctrl.isSomething).toBe(false);
         });
    });

    describe('when isSomething is true', function() {

         beforeEach(function() {
           $stateParams.isSomething = 'true';
         });

         it('should be true', function() {
            // THIS IS FAILING
            expect(ctrl.isSomething).toBe(true);
         });
    });

 });

如何正确模拟不同测试的
$stateParams
的不同状态?

我认为您需要使用更新的scope对象再次实例化控制器

您还存在一些命名问题,请参见下面代码中的注释


我认为您需要使用更新的scope对象再次实例化控制器

您还存在一些命名问题,请参见下面代码中的注释


您遇到的问题是,描述的beforeach('when isSomething is true')在描述的beforeach('SampleCtrl Test')之后求值,即当$stateParams值更改时,控制器已经实例化。正如Matt在他的回答中所写的,您需要在更改发生后实例化控制器

我通常使用一个简单的解决方法来解决这个问题。因为beforeach是在控制器之后实例化的,所以我通常编写一个空it语句,其中不正确的stateparms被发送到控制器并忽略该语句。对于所有之前的it语句,stateParams的更改将发生,控制器将使用正确的变量:

describe('when isSomething is true', function() {
    beforeEach(function() {
         $stateParams.isSomething = 'true';
    });

    it('should take one iteration to set the state parameter', function() {
        // do nothing as the controller will not use the new $stateParams yet
    });

    it('should be true', function() {
        // THIS IS NO LONGER FAILING
        expect(ctrl.isSomething).toBe(true);
    });
});

虽然不是最漂亮的解决方案,但它似乎是最简单的

您遇到的问题是,描述的beforeach('when isSomething is true')在描述的beforeach('SampleCtrl Test')之后求值,即当$stateParams值更改时,控制器已经实例化。正如Matt在他的回答中所写的,您需要在更改发生后实例化控制器

我通常使用一个简单的解决方法来解决这个问题。因为beforeach是在控制器之后实例化的,所以我通常编写一个空it语句,其中不正确的stateparms被发送到控制器并忽略该语句。对于所有之前的it语句,stateParams的更改将发生,控制器将使用正确的变量:

describe('when isSomething is true', function() {
    beforeEach(function() {
         $stateParams.isSomething = 'true';
    });

    it('should take one iteration to set the state parameter', function() {
        // do nothing as the controller will not use the new $stateParams yet
    });

    it('should be true', function() {
        // THIS IS NO LONGER FAILING
        expect(ctrl.isSomething).toBe(true);
    });
});
虽然不是最漂亮的解决方案,但它似乎是最简单的