Javascript newValue始终等于单元测试中AngularJS属性中的oldValue

Javascript newValue始终等于单元测试中AngularJS属性中的oldValue,javascript,unit-testing,angularjs,jasmine,Javascript,Unit Testing,Angularjs,Jasmine,我有一个控制器,它只是监视一个“name”属性,并在任何更改时打印它的新值和旧值 function Ctrl($scope) { $scope.$watch('name', function(newValue, oldValue) { console.log('newValue: ' + newValue + ', oldValue: '+ oldValue); if (newValue !== oldValue) { //...

我有一个控制器,它只是监视一个“name”属性,并在任何更改时打印它的新值和旧值

function Ctrl($scope) {
    $scope.$watch('name', function(newValue, oldValue) {
        console.log('newValue: ' + newValue + ', oldValue: '+ oldValue);
        if (newValue !== oldValue) {
            //...
        }
    }
});
然后我想用Jasmine进行单元测试:

var rootScope, scope, ctrl;
beforeEach(inject(function ($rootScope, $controller) {
    rootScope = $rootScope;
    scope = $rootScope.$new();
    ctrl = $controller('Ctrl', { $scope: scope });
}));

it('should have different old and new values if I set a new name', function() {
    rootScope.name = 'some new name';
    rootScope.$apply();

    //expect the behaviors happen for newValue !== oldValue
});

然后我希望控制台记录一条消息,指示newValue不等于oldValue,但是我总是得到newValue===oldValue。为什么旧价值会丢失?

我认为,这就是行为。当我们第一次调用控制器时,旧值等于新值,因此不会发生任何事情。通常在这种情况下,我们可以写:

if(oldValue === newValue){return;}
我们还可以编写
$watch
如下:

$scope.$watch('name', function () {
    // ....
  });
并且仅当
名称
发生更改时才会调用:

演示1

我不是最团结的大师,无论如何,试试这个流程:

控制器

angular.module('plunker').controller('MyCtrl', function($scope) {

 $scope.watchFunctionCounter= 0;

  $scope.$watch(function () {
    return $scope.name;
},
function (newValue, oldValue) {
    console.log('newValue: ' + newValue + ', oldValue: '+ oldValue);
        if (newValue !== oldValue) {
            $scope.watchFunctionCounter++;
        }
}, true);
});
Unitest

describe('Directive: maybeLink', function() {
 var scope, ctrl;

  beforeEach(function() {
    module('plunker');

    inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      ctrl = $controller('MyCtrl', {$scope: scope});
    });
  });

  afterEach(function() {
        controller = null;
    });

        it('should have different old and new values if I set a new name', function() {
           scope.name = 'some new name';
           scope.$digest();

          expect(scope.watchFunctionCounter).toBe(0); 
         // on this strage the name is undefined, therefore we stay out of "if" statemant

           scope.name = 'diff name';
           scope.$digest();

          expect(scope.watchFunctionCounter).toBe(1);
     });
});

演示2

我所做的是在控制器创建之后立即在beforeach子句中运行摘要:

    beforeEach(inject(function ($rootScope, $controller) {
        rootScope = $rootScope;
        scope = $rootScope.$new();
        ctrl = $controller('Ctrl', { $scope: scope });
        scope.$digest();
    }));

这样,在运行每个测试之前都会完成摘要,并且手表工作正常。

是的,正如您的代码所演示的,让我困惑的是,为什么第一次通过
scope.name='some new name'
设置新值时,您会得到
oldValue
等于
newValue
并且计数器没有递增?这就是我的困惑:-(