Я новичок в тестировании Jasmine и ищу "лучшую практику" для модульного тестирования сервиса AngularJS с отслеживанием состояния. Большинство руководств, которые я мог найти, фокусировались на тестовых примерах, которые запускают атомарные вызовы служб без сохранения состояния.
Это хорошо соответствует синтаксису Жасмин
it("should do something", function(){ expect(target.doSomething()).toBe... })
Однако я не нашел очевидного способа расширить этот шаблон до контрольного примера, который включает в себя несколько вызовов одной или нескольких функций службы.
Давайте представим такую услугу:
angular.module("someModule").factory("someService", function(){
return {
enqueue: function(item){
// Add item to some queue
}
}
});
Для такой службы имеет смысл проверить, что последовательные вызовы enqueue()
обрабатывают элементы в правильном порядке. Это включает в себя написание тестового примера, который вызывает enqueue()
несколько раз и проверяет конечный результат (который, очевидно, не может быть достигнут с помощью такой простой службы, как приведенная выше, но это не главное ...)
Что не работает:
describe("Some service", function(){
// Initialization omitted for simplicity
it("should accept the first call", function() {
expect(someService.enqueue(one)).toBe... // whatever is correct
});
it("should accept the second call", function() {
expect(someService.enqueue(two)).toBe... // whatever is correct
});
it("should process items in the correct order", function() {
// whatever can be used to test this
});
});
Приведенный выше код (который на самом деле определяет не один, а три тестовых случая) дает сбой случайным образом, так как три тестовых случая выполняются ... так же, как случайным образом.
Плакат в этой ветке предположил, что при разбиении кода на несколько describe
блоков они будут выполняться в указанном порядке, но, опять же, похоже, что это отличается от одной версии Jasmine к другой ( по другим постерам в той же ветке). Более того, выполнение наборов и тестов в случайном порядке, кажется, является намеченным способом; даже если бы по настройке было возможно переопределить это поведение, это, вероятно, НЕ верный путь.
Таким образом, похоже, что единственный правильный способ тестирования сценария с несколькими вызовами - это сделать ОДИН тестовый пример, например:
describe(("Some service", function(){
// Initialization omitted for simplicity
it("should work in my complex scenario", function(){
expect(someService.enqueue(one)).toBe... // whatever is correct
expect(someService.enqueue(two)).toBe... // whatever is correct
expect(/* whatever is necessary to ensure the order is correct */);
});
});
Хотя с технической точки зрения это выглядит логичным путем (в конце концов, сложный сценарий - это один тестовый пример, а не три), шаблон «описание + код» Жасмина в этой реализации выглядит нарушенным как:
- Нет способа связать сообщение с каждым «подшагом», которое может завершиться неудачей в тестовом примере;
- Описание для единственного "it" неизбежно громоздко, как в примере выше, чтобы действительно сказать что-то полезное о сложном сценарии.
Это заставляет меня задуматься, является ли это единственно правильным решением (или не так ли?) Для такого рода нужд тестирования. Опять же, я особенно заинтересован в том, чтобы «делать это правильно», а не использовать какой-то хак, который заставил бы его работать ... там, где он не должен.