2015-11-17 21 views
8

Kiểm tra đơn vị một chỉ thị góc không phải là rất khó, nhưng tôi phát hiện ra rằng có nhiều cách khác nhau để làm điều đó.Làm thế nào để kiểm tra đơn vị một chỉ thị góc

Với mục đích của bài viết này, cho phép giả định các chỉ thị sau

angular.module('myApp') 
    .directive('barFoo', function() { 
     return { 
      restrict: 'E', 
      scope: true, 
      template: '<p ng-click="toggle()"><span ng-hide="active">Bar Foo</span></p>', 
      controller: function ($element, $scope) { 
       this.toggle() { 
        this.active = !this.active; 
       } 
      } 
     }; 
    }); 

Bây giờ tôi có thể nghĩ đến hai cách để kiểm tra đơn vị

Phương pháp này 1:

describe('Directive: barFoo', function() { 
    ... 
    beforeEach(inject(function($rootScope, barFooDirective) { 
     element = angular.element('<bar-foo></bar-foo>'); 
     scope = $rootScope.$new(); 
     controller = new barFooDirective[0].controller(element, scope); 
    })); 

    it('should be visible when toggled', function() { 
     controller.toggle(); 
     expect(controller.active).toBeTruthy(); 
    }); 
}); 

Phương pháp 2 :

beforeEach(inject(function ($compile, $rootScope) { 
    element = angular.element('<bar-foo></bar-foo>'); 
    scope = $rootScope.$new(); 
    $compile(element)(scope); 
    scope.$digest(); 
})); 

it ('should be visible when toggled', function() { 
    element.click(); 
    expect(element.find('span')).not.toHaveClass('ng-hide'); 
}); 

Vì vậy, tôi tò mò những gì của pro và khuyết điểm là của cả hai phương pháp và đó là một trong những mạnh mẽ nhất?

+1

tôi cho rằng cách nhấp vào phần tử trong kiểm tra đơn vị cũng giống như các phương pháp điều khiển thử nghiệm trong thước đo – Appeiron

Trả lời

1

Điều tôi thích làm là tạo các câu chuyện về thử nghiệm của tôi như ví dụ giả này.

'use strict'; 

describe('app controller', function() { 

    var scope; 

    ... 

    beforeEach(angular.mock.module('MyModule')); 

    it('should have properties defined', function() { 

    expect(scope.user).toEqual(user); 
    ...  

    }); 

    it('should have getFaqUrl method', function() { 

    expect(scope.getFaqUrl).toEqual(refdataService.getFaqUrl); 

    }); 

    it('should signout and delete user data from local storage', function() { 

    ... 

    }); 

}); 

Vì vậy, tôi đoán bạn không nêu rõ trong ví dụ thứ hai, nhưng trong trường hợp bạn đã làm, hãy sử dụng mô tả bao vây luôn khi thử nghiệm, chỉ cần thực hành tốt.

Đối với bản thân bài kiểm tra, tôi khuyên bạn nên tránh phương pháp mà bạn gọi cho phạm vi một cách rõ ràng. $ Digest(), đặc biệt là vì nó không có vẻ cần thiết cho mục đích kiểm tra của bạn.

thời gian ngắn, tôi sẽ đi cho phương pháp 1.

+0

Cảm ơn rất nhiều cho câu trả lời. Bạn có thể cập nhật cho bạn bài đăng với ví dụ về cách thử nghiệm của bạn giống như kết hợp với một câu chuyện không? –

+0

Xin lỗi tôi chỉ chỉnh sửa ngay bây giờ, tôi đang tìm kiếm một số ví dụ giả, vì tôi không thể chia sẻ mã sản phẩm .. nhưng điều này giải thích những gì tôi đang nghĩ về sự thiếu sót và đối với mỗi bộ điều khiển, thêm một câu chuyện như bộ – desicne

1

Tôi thấy phương pháp đầu tiên hơn "đúng" bởi vì nó không phụ thuộc vào một sự kiện click. Tôi tin rằng nếu bạn muốn kiểm tra việc nhấp vào một phần tử và các hiệu ứng của nó, bạn nên sử dụng thước đo góc và chỉ sử dụng hoa nhài cho các bài kiểm tra đơn vị. Bằng cách đó, bạn sẽ có một sự tách biệt tốt đẹp giữa các bài kiểm tra đơn vị và các bài kiểm tra UI.

Ngoài ra, tính năng này giúp kiểm tra dễ bảo trì hơn. ví dụ. nếu bạn quyết định bắn toggle trên di chuột thay vì nhấp chuột trong phương pháp thứ hai, bạn cũng sẽ phải cập nhật các thử nghiệm.

+0

Bạn cho rằng bạn phương thức đầu tiên bởi vì phương thức thứ hai thực hiện điều '.click()'? –

+0

@ JeanlucaScaljeri yap, tôi có nghĩa là người đầu tiên. Tôi sửa nó rồi. cám ơn. –

+0

Thử nghiệm đơn vị được tạo cho các phương pháp thử nghiệm trả về và tác động đến dữ liệu và kiểm tra theo hành vi (nhấp chuột, v.v.) được sử dụng để kiểm tra tương tác người dùng thực tế. – Appeiron

2

Đây là cách bạn kiểm tra chỉ thị AngularJS của bạn:

describe('Directive: barFoo', function() { 
 
    var createElement, element, parentScope, directiveScope; 
 
    
 
    beforeEach(module('myApp')); 
 

 
    beforeEach(inject(function($injector) { 
 
    var $compile = $injector.get('$compile'); 
 
    var $rootScope = $injector.get('$rootScope'), 
 

 
    parentScope = $rootScope.$new(); 
 
    parentScope.paramXyz = ... <-- prepare whatever is expected from parent scope 
 

 
    createElement = function() { 
 
     element = $compile('<bar-foo></bar-foo>')(parentScope); 
 
     directiveScope = element.isolateScope(); 
 
     parentScope.$digest(); 
 
     $httpBackend.flush(); <-- if needed 
 
    }; 
 
    })); 
 

 

 
    it('should do XYZ', function() { 
 
    parentScope.xyz = ... <-- optionnal : adjust scope according to your test 
 
    createElement(); 
 

 
    expect(...) <-- whatever, examples : 
 

 
    var submitButton = element.find('button[type="submit"]'); 
 
    expect(submitButton).to.have.value('Validate'); 
 
    expect(submitButton).to.be.disabled; 
 
    submitButton.click(); 
 
    });

+0

Cách tiếp cận này ít nhiều giống như phương pháp 2. Bạn có thể cung cấp một số lý lẽ tại sao điều này tốt hơn phương pháp 1 không? –

+0

@JeanlucaScaljeri trong phương pháp 1) bạn phải tạo bộ điều khiển theo cách thủ công và trong phương pháp 2) bạn có thêm một bước.Ví dụ tôi đề xuất (lấy từ các thử nghiệm thực tế của chúng tôi trong công ty của tôi) cũng hiển thị một cấu trúc thử nghiệm cho phép thử nghiệm dễ dàng hơn, bằng cách cho phép thêm một số lần in * trước * instantiating chỉ thị với 'createElement()'. Cũng lưu ý sự tách biệt rõ ràng giữa phạm vi cha và con. – Offirmo

+0

Tôi thích phương pháp này. Tôi mới làm quen với các chỉ thị thử nghiệm. Tôi tự hỏi làm thế nào bạn xác định một chỉ thị cụ thể để kiểm tra? Điều đó có cần thiết không? – Winnemucca

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