简体   繁体   English

AngularJS 单元测试 element.bind

[英]AngularJS Unit Test element.bind

Inside a directive of mine called by data-type-ahead I have the following, in a series of events:在我的由data-type-ahead调用的directive ,我在一系列事件中包含以下内容:

$scope.test = 5;

// Bind blur event and clear the value of 
element.bind('blur', function(){
    $scope.test = 0;
});

I have tried a multitude of things to use in a unit test to correctly test the functionality of this blur event however I have not been successful.我已经尝试了很多在单元测试中使用的东西来正确测试这个blur事件的功能,但是我没有成功。 I have seen mention of the function triggerHandler .我已经看到提到函数triggerHandler Here is my attempt at the unit test:这是我在单元测试中的尝试:

//Inject $compile and $rootScope before each test.
beforeEach(inject(function(_$compile_, _$rootScope_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;

    $scope = $rootScope.$new();
    $scope.test = 5

    html = angular.element('<input type="text" data-type-ahead/>');

    //Apply $scope to directive html.
    directive = $compile(html)($scope);

    //Trigger digest cycle.
    $scope.$digest();
}));

it('should trigger the events bound to the blur event on the directive', function() {
    html.triggerHandler('blur')
    expect($scope.test).toEqual(0);
});

However this is failing because $scope.test is remaining on 5. Is it the html element is incorrect, do I need another $digest or $apply for after I trigger the event?但是这是失败的,因为$scope.test仍然在 5. html 元素不正确,触发事件后我是否需要另一个$digest$apply

You have 2 ways of getting this to work.您有 2 种方法可以使其发挥作用。 The first is adding a timeout to your method ( docs ):第一个是为您的方法( docs )添加超时:

// somewhere above add - 
var originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

// in your beforeEach

beforeEach(function(){
 html.triggerHandler('blur');
  setTimeout(function(){
  done();
 }, 1000);
});

it('should trigger the events bound to the blur event on the directive',  
   function() {
    expect($scope.test).toEqual(0);
   }
);

I believe this to be "less good" practice (bad or worse is too negative a word for testing - the moment you test, you are already better :)).我相信这是“不太好”的做法(坏或更糟对于测试来说太消极了——你测试的那一刻,你已经更好了:))。 In general, I try to avoid testing async, because eventually my methods (aka units) are sync inside.一般来说,我尽量避免测试异步,因为最终我的方法(又名单元)在内部是同步的。

The "better practice" would be to write the method that changes the value like this: “更好的做法”是编写更改值的方法,如下所示:

// in the directive's ctrl
this.changeValue = function changeValue{
  $scope.test = 0;
}

// later on set the watcher
// Bind blur event and clear the value of 
$element.bind('blur', this.changeValue);

And then test the method itself instead of testing it async.然后测试方法本身而不是异步测试它。 You could test the $element.bind (via the spyOn(element, 'bind')) if you like to see that your ctrl/link methods create the binding.如果您希望看到您的 ctrl/link 方法创建绑定,您可以测试 $element.bind(通过 spyOn(element, 'bind'))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM