8

Есть ли у кого-нибудь идеи, как издеваться над $ httpBackend в угловых тестах e2e? Идея заключается в том, чтобы пропустить XHR-запросы при выполнении тестов на travis-ci. Я использую karma для прокси-активов и частичных файлов из моего приложения rails, работающего на travis. Я хочу провести приемочное тестирование без реальных запросов к БД.

Вот часть моего файла конфигурации карма:

... 
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/' 
}; 
... 

Вот часть моей спецификации файла:

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(); 
})); 

Я пытался получить $ httpBackend обслуживание через $ инжектором:

$injector.get('$httpBackend') 

Но это не тот, который используется внутри iframe, где выполняются мои тесты.

Следующая попытка я сделал использую angular.scenario.dsl, вот код выборочный: пример

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); 
    }); 
    }; 
}); 

Использования:

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

Это приводит к следующей ошибке:

<$httpBackend listing> has no method 'expectGET' 

Итак, на данный момент я понятия не имею о следующем шаге. Кто-нибудь пробовал делать что-то подобное, действительно ли этот тип обрушения возможен?

+0

как вы настраиваете свою карму, чтобы иметь «инъекцию» в своей спецификации? Я продолжал получать ReferenceError для своих тестов. – wakandan

ответ

0

Это больше похоже на тестирование единиц измерения/спецификации. Вообще говоря, вы должны использовать mocks в тестах unit/spec, а не в тестах e2e/integration. В основном, подумайте о тестах e2e как утверждении ожиданий в основном интегрированном приложении ... издевательствах о виде поражения, цель тестирования e2e. На самом деле, я не уверен, как карам вставлял угловое mocks.js в запущенное приложение.

Спецификации тест может выглядеть примерно так ...

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

Код не связан с вопросом. Вопрос не в модульных тестах, а в коде для тестовых тестов Jasmine. «инъекция» не определена в тестах e2e. –

7

Если вы действительно пытаетесь дразнить из бэкенда в тесте ЕоГО (эти тесты называются сценариями, в то время как функции используются для модульного тестирования) то это то, что я сделал в проекте, над которым я работал раньше.

Заявка, которую я тестировал, называлась studentsApp. Это было приложение для поиска студентов путем запроса REST api. Я хотел протестировать приложение, не запрашивая при этом api.

Я создал приложение E2E под названием studentsAppDev, которое я вводил studentsApp и ngMockE2E в. Там я определяю, какие вызовы должен ожидать mockBackend и какие данные должны возвращаться. Ниже приведен пример моего studentsAppDev файла:

"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([...]); 
}); 

Тогда у меня есть первый шаг в моем сервере Дженкинс CI заменить studentsApp с studentsAppDev и добавить ссылку на angular-mocks.js в главном файле index.html.

+3

Не нужно настраивать и создавать отдельное приложение только для насмешек $ httpBackend. Я описал, как настроить его так, чтобы он мог использоваться как для тестирования unit & E2E целиком здесь: http://blogs.burnsidedigital.com/2013/09/and-httpbackend-mock-for-all-unit-e2e- Дегустации /. – Dida

+0

О, это хорошее решение Dida, спасибо, что напишите. Это определенно то, что я рассмотрю в следующий раз, когда мне придется издеваться над бэкэндом. –

+0

@Dida Ссылка выше не работает.Можете ли вы дать краткое объяснение того, что вы сделали? Может быть, как новый ответ. Благодарю. – Ena

1

Излучение вашего бэкэнда - важный шаг в создании сложного углового приложения.Это позволяет проводить тестирование без доступа к бэкэнд, вы не проверяете вещи дважды, и есть меньше зависимостей, о которых можно беспокоиться.

Angular Multimocks - это простой способ проверить, как ваше приложение ведет себя с различными ответами API.

Он позволяет определять наборы откликов API для разных сценариев как файлы JSON.

Он также позволяет легко менять сценарии. Он делает это, позволяя выкладывать «сценарии» из разных файловых файлов.

Как добавить его в приложение

После добавления необходимых файлов в вашей странице, просто добавьте scenario как зависимость к приложению:

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

После того, как вы добавили это приложение вы может начать создавать mocks для вызовов API.

Допустим, ваше приложение делает следующий API вызов:

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

Вы можете создать default макет файла:

Примердлительногопребывания someGames.json

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

При загрузке приложения, звонки до /games вернет 200 и {"games": [{"name": "Legend of Zelda"}]}

Теперь скажем, что вы хотите вернуть другой ответ для одного и того же вызова API, вы можете поместить приложение в другой сценарий, изменив URL-адрес, например. ?scenario=no-games

no-games сценарий может использовать другой макет файла, позволяет сказать, что один такой:

Пример noGames.json

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

Теперь при загрузке приложения, звонки /games вернется 200 и {"games": []}

Сценарии состоят из различных JSON mocks в манифесте следующим образом:

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

Затем вы можете исключить файлы-макеты и убрать зависимость scenario в своем производственном приложении.

Смежные вопросы