2015-01-16 2 views
2

Сценариемуглового блока испытание изменение состояния с решимостью

Я построил форму поиска с 2 состояниями: Первого состояния запускает второй (OnClick), и устанавливает некоторые параметры состояния с $ state.go функции(). Второе состояние имеет функцию разрешения, которая получает параметр состояния и решает результаты поиска.

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

Вопрос

Как сделать модульное тестирование для этого?

Первоначальная идея заключается в том, что я должен сделать тест, который «должен вызвать поиск с помощью поиска и перейти к странице результатов». Он терпит неудачу, потому что состояния не разрешают правильно с жасмином. Иногда это «заблокировано» в первом состоянии, в других сценариях состояние всегда «».

Когда я удалял блок разрешения из конфигурации, он работает так, как ожидалось, и тесты проходят, поэтому проблема явно находится в блоке разрешения. Странно, что я не получаю ошибки «неизвестного провайдера».

Любые мысли или идеи, как это исправить?

Ближайший вопрос о StackOverflow был таков: Angular ui router unit testing (states to urls) Но пользователь вызывает изменение состояния вручную, в то время как в моем случае это вызывается другой функцией.

Unit код теста:

describe('SearchController tests', function(){ 
    var ctrl, $state, $rootScope, $httpBackend; 

    // instantiate the app to provide all the dependencies 
    beforeEach(module('MyApp')); 

    beforeEach(inject(function($controller, _$state_, _$rootScope_, _$httpBackend_) { 
     ctrl = $controller('SearchController', {}); 
     $state = _$state_; 
     $httpBackend = _$httpBackend_; 
     $rootScope = _$rootScope_; 

     // mocking the views 
     // (instead of including stateMock script from the post, just to simplify) 
     $httpBackend.expectGET("search.html").respond("<input ng-model='vm.searchTerm'><button ng-click='vm.search()'>Search</button>"); 
     $httpBackend.expectGET("search-results.html").respond("<div ng-repeat='res in vm.results'> {{ res }}</div>"); 

     $state.go('search'); 
     $rootScope.$digest(); 
    })); 

    it('should trigger a search with searchTerm "rabbit" and change state to search results page', function(){ 
     ctrl.searchTerm = 'rabbit'; 
     $state.go('search'); 
     ctrl.search(); 
     $rootScope.$digest(); 
     expect($state.current.name).toBe('search-results'); 
    }) 
}); 

Plunker

http://plnkr.co/edit/6qiYCvCu1LftLzQRyTJy?p=preview

ответ

0

Этот ответ другой вариант моей записки в вопросе:

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

Что означает, когда изменяется состояние «Поиск-результаты», впрыскивается «search_results» будет обещание, которое будет по-прежнему должны быть решены во втором состоянии, означая SearchApi еще не испробованы и решены.

Как я уже говорил, я предпочитаю решать обетования между, поскольку он кажется более чистым, а блок конфигурации содержит всю необходимую информацию для удобства чтения кода.

Unit решение тестовой задачи:

Я решил мой главный вопрос, модульный тест. Проблема была довольно распространена, я не включил модуль, который содержит определение родительского состояния. В plunker демо я поставил все зависимость в одном модуле, для целей демонстрации, так что все, что я должен был сделать в тесте блока было inlude всего модуля:

beforeEach(module('MyApp')); 

Реальным приложение гораздо больше , и разделены в нескольких модулях, компонентах и ​​состояниях, следующих AngularAtom—Component-based organization.

Одна из хороших сторон этого подхода заключается в том, цитата:

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

Даунсайд этого конкретного сделать каждое состояние модуля подходом является то, что он делает модульное тестирование немного более сложное с вложенными состояниями.

Допустим, мы имеем тройное вложенное состояние (которое не является настолько не-обычным сценарием):

  • State1
    • app.js
    • config.js
    • state1.first
      • приложение.js
      • config.js ...
      • state1.first.list
        • app.js
        • config.js
        • список-controller.js
        • список-view.html ...
      • state1.first. подробно ...
    • state1.second ...

Вы хотите сделать модульное тестирование для list-controller.js, который находится под state1.first.list состояния. Чтобы создать единичный тест с моего первого сообщения (проверьте функцию в state1.first.list, которая изменит состояние на state1.first.detail), ваш тест должен иметь импорт для: state1, state1.first и state1.first.detail.

beforeEach(module('state1')); 
beforeEach(module('state1.first')); 
beforeEach(module('state1.first.detail')); 

Причина в том, что каждый модуль содержит собственную конфигурацию состояния в config.js.Если вы попытаетесь выполнить этот тест, только импортируя state1.first.list и state1.first.detail, он не сработает без сообщения об ошибке. Причина в том, что отсутствует конфигурация состояния (состояний) родительских (ов), которая определена в разных модулях. Жасмин в сочетании с PhantomJS по умолчанию не регистрирует такие ошибки, поэтому такого рода ошибки немного сложнее обнаружить, но это другая проблема.

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

+0

plunker please ... –

+0

Я думаю, что это пересекает линию в интеграционное тестирование. – BobDoleForPresident

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