2014-06-11 16 views
6

Tôi có bộ điều khiển có đồng hồ sử dụng debounce từ lodash để trì hoãn lọc danh sách 500ms.Cách kiểm tra đồng hồ AngularJS bằng chức năng gỡ lỗi với Jasmine

$scope.$watch('filter.keywords', _.debounce(function() { 
    $scope.$apply(function() { 
    $scope.filtered = _.where(list, filter); 
    }); 
}, 500)); 

Tôi đang cố viết một bài kiểm tra Jasmine mô phỏng nhập từ khóa bộ lọc không được tìm thấy tiếp theo từ khóa được tìm thấy.

Nỗ lực ban đầu của tôi là sử dụng $ digest sau khi gán giá trị mới cho từ khóa mà tôi cho là không hoạt động do bị từ chối.

it('should filter list by reference', function() { 
    expect(scope.filtered).toContain(item); 
    scope.filter.keywords = 'rubbish'; 
    scope.$digest(); 
    expect(scope.filtered).not.toContain(item); 
    scope.filter.keywords = 'test'; 
    scope.$digest(); 
    expect(scope.filtered).toContain(item); 
}); 

Vì vậy, tôi đã thử sử dụng $ timeout, nhưng điều đó không hoạt động.

it('should filter list by reference', function() { 
    expect(scope.filtered).toContain(item); 
    $timeout(function() { 
    scope.filter.keywords = 'rubbish'; 
    }); 
    $timeout.flush(); 
    expect(scope.filtered).not.toContain(item); 
    $timeout(function() { 
    scope.filter.keywords = 'test'; 
    }); 
    $timeout.flush(); 
    expect(scope.filtered).toContain(item); 
}); 

Tôi cũng đã cố gắng cho $ timeout một giá trị lớn hơn 500ms được đặt trên debounce.

Người khác đã giải quyết vấn đề này như thế nào?

CHỈNH SỬA: Tôi đã tìm thấy giải pháp để bao bọc kỳ vọng trong hàm $ timeout, sau đó gọi $ áp dụng cho phạm vi.

it('should filter list by reference', function() { 
    expect(scope.filtered).toContain(item); 
    scope.filter.keywords = 'rubbish'; 
    $timeout(function() { 
    expect(scope.filtered).not.toContain(item); 
    }); 
    scope.$apply(); 
    scope.filter.keywords = 'test'; 
    $timeout(function() { 
    expect(scope.filtered).toContain(item); 
    }); 
    scope.$apply(); 
}); 

tôi vẫn quan tâm để biết liệu phương pháp này là tốt nhất mặc dù.

Trả lời

4

Đây là phương pháp không tốt. Bạn nên sử dụng một cuộc tranh luận theo góc cụ thể như this sử dụng thời gian chờ $ thay vì setTimeout. Bằng cách đó, bạn có thể làm

$timeout.flush(); 
    expect(scope.filtered).toContain(item); 

và thông số kỹ thuật sẽ chuyển như mong đợi.

1

Tôi đã sử dụng này:

beforeEach(function() { 
    ... 
    spyOn(_, 'debounce').and.callFake(function (fn) { 
     return function() { 
      //stack the function (fn) code out of the current thread execution 
      //this would prevent $apply to be invoked inside the $digest 
      $timeout(fn); 
     };    
    }); 
}); 

function digest() { 
    //let the $watch be invoked 
    scope.$digest(); 
    //now run the debounced function 
    $timeout.flush(); 
} 

it('the test', function() { 
    scope.filter.keywords = ...; 
    digest(); 
    expect(...); 
}); 

Hy vọng nó giúp

Các vấn đề liên quan