8

Có ai có ý tưởng làm thế nào để giả lập $ httpBackend trong các thử nghiệm e2e góc? Ý tưởng này đang xâu chuỗi các yêu cầu XHR trong khi chạy thử nghiệm trên travis-ci. Tôi đang sử dụng nghiệp lực cho tài sản proxy và partials từ ứng dụng đường ray của tôi chạy trên chuyến đi. Tôi muốn thực hiện kiểm tra chấp nhận mà không cần truy vấn DB thực.

Dưới đây là một phần của tập tin cấu hình nghiệp của tôi:

... 
files = [ 
    MOCHA, 
    MOCHA_ADAPTER, 

    'spec/javascripts/support/angular-scenario.js', 
    ANGULAR_SCENARIO_ADAPTER, 

    'spec/javascripts/support/angular-mocks.js', 
    'spec/javascripts/e2e/**/*_spec.*' 
]; 
... 

proxies = { 
    '/app': 'http://localhost:3000/', 
    '/assets': 'http://localhost:3000/assets/' 
}; 
... 

Dưới đây là một phần của tập tin spec của tôi:

beforeEach(inject(function($injector){ 
    browser().navigateTo('/app'); 
})); 

it('should do smth', inject(function($rootScope, $injector){ 
    input('<model name>').enter('smth'); 
    //this is the point where I want to stub real http query 
    pause(); 
})); 

Tôi đã cố gắng để nhận được $ httpBackend dịch vụ thông qua $ injector:

$injector.get('$httpBackend') 

Nhưng đây không phải là cái được sử dụng bên trong khung nội tuyến nơi các thử nghiệm của tôi chạy.

Các thử hôm sau tôi đã được sử dụng angular.scenario.dsl, đây là mã samle:

angular.scenario.dsl('mockHttpGet', function(){ 
    return function(path, fakeResponse){ 
    return this.addFutureAction("Mocking response", function($window, $document, done) { 
     // I have access to window and document instances 
     // from iframe where my tests run here 
     var $httpBackend = $document.injector().get(['$httpBackend']); 
     $httpBackend.expectGET(path).respond(fakeResponse) 
     done(null); 
    }); 
    }; 
}); 

Cách sử dụng Ví dụ:

it('should do smth', inject(function($rootScope, $injector){ 
    mockHttpGet('<path>', { /* fake data */ }); 
    input('search.name').enter('mow'); 
    pause(); 
})); 

Điều này dẫn đến lỗi sau:

<$httpBackend listing> has no method 'expectGET' 

Vì vậy, tại thời điểm này tôi không có ý tưởng về bước tiếp theo. Có ai đã cố gắng làm một cái gì đó như thế này, là loại stubbing thực sự có thể?

+0

cách cấu hình nghiệp của bạn để có chức năng "tiêm" trong thông số của bạn? Tôi tiếp tục nhận được ReferenceError cho các bài kiểm tra của tôi – wakandan

Trả lời

0

Điều này giống như thử nghiệm đơn vị/thông số kỹ thuật hơn. Nói chung, bạn nên sử dụng mocks trong các bài kiểm tra đơn vị/spec hơn là các bài kiểm tra e2e/tích hợp. Về cơ bản, hãy nghĩ về các bài kiểm tra e2e như khẳng định kỳ vọng về một ứng dụng được tích hợp chủ yếu ... nhạo báng những thứ thất bại với mục đích kiểm tra e2e. Trong thực tế, tôi không chắc làm thế nào karam sẽ chèn angular-mocks.js vào ứng dụng đang chạy.

Các xét nghiệm đặc tả có thể trông giống như ...

describe('Controller: MainCtrl', function() { 
    'use strict'; 

    beforeEach(module('App.main-ctrl')); 

    var MainCtrl, 
     scope, 
     $httpBackend; 

    beforeEach(inject(function ($controller, $rootScope, $injector) { 
     $httpBackend = $injector.get('$httpBackend'); 
     $httpBackend.when('GET', '/search/mow').respond([ 
      {} 
     ]); 
     scope = $rootScope.$new(); 
     MainCtrl = $controller('MainCtrl', { 
      $scope: scope 
     }); 
    })); 

    afterEach(function() { 
     $httpBackend.verifyNoOutstandingExpectation(); 
     $httpBackend.verifyNoOutstandingRequest(); 
    }); 

    it('should search for mow', function() { 
     scope.search = 'mow'; 
     $httpBackend.flush(); 
     expect(scope.accounts.length).toBe(1); 
    }); 
}); 
+0

Mã không liên quan đến câu hỏi - câu hỏi không phải là về kiểm tra đơn vị và mã là dành cho các bài kiểm tra đơn vị Jasmine. 'inject' không được định nghĩa trong các phép thử e2e. –

7

Nếu bạn đang thực sự cố gắng để thử ra các backend trong một thử nghiệm E2E (các xét nghiệm này được gọi là kịch bản, trong khi Specs được sử dụng để kiểm tra đơn vị) thì đây là những gì tôi đã làm trong một dự án mà tôi đã làm trước đó.

Đơn đăng ký tôi đã thử nghiệm được gọi là studentsApp. Nó là một ứng dụng để tìm kiếm các sinh viên bằng cách truy vấn một api REST. Tôi muốn thử nghiệm ứng dụng mà không thực sự truy vấn api đó.

Tôi đã tạo một ứng dụng E2E có tên studentsAppDev mà tôi tiêm studentsAppngMockE2E vào. Ở đó tôi xác định những gì các cuộc gọi mockBackend nên mong đợi và những gì dữ liệu để trở về. Sau đây là một ví dụ về tập tin studentsAppDev tôi:

"use strict"; 

// This application is to mock out the backend. 
var studentsAppDev = angular.module('studentsAppDev', ['studentsApp', 'ngMockE2E']); 
studentsAppDev.run(function ($httpBackend) { 

    // Allow all calls not to the API to pass through normally 
    $httpBackend.whenGET('students/index.html').passThrough(); 

    var baseApiUrl = 'http://localhost:19357/api/v1/'; 
    var axelStudent = { 
     Education: [{...}], 
     Person: {...} 
    }; 
    var femaleStudent = { 
     Education: [{...}], 
     Person: {...} 
    }; 
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&') 
     .respond([axelStudent, femaleStudent]); 
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axel&')  
     .respond([axelStudent, femaleStudent]); 
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=1&') 
     .respond([axelStudent]); 
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=2&') 
     .respond([femaleStudent]); 
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=3&')  
     .respond([]); 

    ... 

    $httpBackend.whenGET(baseApiUrl + 'departments/?teachingOnly=true') 
     .respond([...]); 
    $httpBackend.whenGET(baseApiUrl + 'majors?organization=RU').respond([...]); 
}); 

Sau đó, tôi có một bước đầu tiên trong máy chủ Jenkins CI của tôi để thay thế studentsApp với studentsAppDev và thêm một tham chiếu đến angular-mocks.js trong file index.html chính.

+3

Không cần phải thiết lập và tạo một ứng dụng riêng biệt chỉ để chế nhạo $ httpBackend. Tôi mô tả làm thế nào để thiết lập nó để nó có thể được sử dụng cho cả hai đơn vị & E2E thử nghiệm hoàn toàn ở đây: http://blogs.burnsidedigital.com/2013/09/and-httpbackend-mock-for-all-unit-e2e- thử nghiệm /. – Dida

+0

Oh đó là một giải pháp tốt Dida, cảm ơn vì đã viết lên. Nó chắc chắn là một cái gì đó tôi sẽ xem xét trong thời gian tới tôi sẽ phải thử ra các phụ trợ. –

+0

@Dida Link ở trên hiện không hoạt động.Bạn có thể cung cấp giải thích ngắn gọn về những gì bạn đã làm không? Có thể là một câu trả lời mới. Cảm ơn. – Ena

1

Việc loại bỏ chương trình phụ trợ của bạn là một bước quan trọng trong việc xây dựng ứng dụng Góc phức tạp.Nó cho phép thử nghiệm được thực hiện mà không cần truy cập vào backend, bạn không kiểm tra mọi thứ hai lần và có ít phụ thuộc hơn để lo lắng.

Angular Multimocks là cách đơn giản để kiểm tra cách ứng dụng của bạn hoạt động với các phản hồi khác nhau từ API.

Nó cho phép bạn xác định tập hợp các phản hồi API mô phỏng cho các kịch bản khác nhau dưới dạng tệp JSON.

Nó cũng cho phép bạn thay đổi kịch bản dễ dàng. Nó thực hiện điều này bằng cách cho phép bạn soạn "kịch bản" ra khỏi các tệp giả khác nhau.

Làm thế nào để thêm nó vào ứng dụng của bạn

Sau khi thêm các tập tin cần thiết vào trang của bạn, chỉ cần thêm scenario như một phụ thuộc vào ứng dụng của bạn:

angular 
    .module('yourAppNameHere', ['scenario']) 
    // Your existing code here... 

Một khi bạn đã thêm vào này để ứng dụng của bạn, bạn có thể bắt đầu tạo mocks cho các cuộc gọi API.

phép nói rằng ứng dụng của bạn thực hiện cuộc gọi API sau:

$http.get('/games').then(function (response) { 
    $scope.games = response.data.games; 
}); 

Bạn có thể tạo một default tập tin giả:

Ví dụ về someGames.json

{ 
    "httpMethod": "GET", 
    "statusCode": 200, 
    "uri": "/games", 
    "response": { 
    "games": [{"name": "Legend of Zelda"}] 
    } 
} 

Khi bạn tải ứng dụng của bạn, cuộc gọi đến /games sẽ trả lại 200{"games": [{"name": "Legend of Zelda"}]}

Bây giờ, giả sử bạn muốn trả về một phản hồi khác cho cùng một cuộc gọi API, bạn có thể đặt ứng dụng trong một trường hợp khác bằng cách thay đổi URL, ví dụ: ?scenario=no-games

Kịch bản no-games có thể sử dụng một tập tin giả khác nhau, cho phép nói một như thế này:

Ví dụ về noGames.json

{ 
    "httpMethod": "GET", 
    "statusCode": 200, 
    "uri": "/games", 
    "response": { 
    "games": [] 
    } 
} 

Bây giờ khi bạn tải ứng dụng của bạn, các cuộc gọi đến /games sẽ trở lại 200{"games": []}

Các tình huống bao gồm nhiều JSON khác nhau trong một tệp kê khai như sau:

{ 
    "_default": [ 
    "games/someGames.json" 
    ], 
    "no-games": [ 
    "games/noGames.json" 
    ] 
} 

Sau đó, bạn có thể loại trừ các tệp giả và loại bỏ sự phụ thuộc scenario trong ứng dụng sản xuất của mình.

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