Вот мой конкретный сценарий.
У меня есть класс QueryQueue, который является оболочкой класса QueryTask в ArcGIS API for Flex. Это позволяет мне легко ставить в очередь несколько задач запроса для выполнения. Вызов QueryQueue.execute() перебирает все задачи в моей очереди и вызывает их метод выполнения.
Когда все результаты будут получены и обработаны, QueryQueue отправит завершенное событие. Интерфейс моего класса очень прост.
public interface IQueryQueue
{
function get inProgress():Boolean;
function get count():int;
function get completed():ISignal;
function get canceled():ISignal;
function add(query:Query, url:String, token:Object = null):void;
function cancel():void;
function execute():void;
}
Чтобы метод QueryQueue.execute считался успешным, должно произойти несколько вещей.
task.executeдолжен вызываться для каждой задачи запроса один и только один разinProgress = trueпока ожидаются результатыinProgress = falseпосле обработки результатовcompletedотправляется после обработки результатовcanceledникогда не вызывается- Обработка, выполняемая в очереди, правильно обрабатывает и упаковывает результаты запроса.
С чем я борюсь, так это с тем, чтобы разбить эти тесты на читаемые, логические и поддерживаемые тесты.
Логически я тестирую одно состояние, то есть состояние успешного выполнения. Это предполагает, что один модульный тест, который утверждает, что пункты с 1 по 6 выше, верны.
[Test] public mustReturnQueryQueueEventArgsWithResultsAndNoErrorsWhenAllQueriesAreSuccessful:void
Однако название теста не является информативным, поскольку оно не описывает всего, что должно быть правдой, чтобы считаться пройденным тестом.
Чтение в Интернете (включая здесь и в programmers.stackexchange.com) существует значительный лагерь, который утверждает, что модульные тесты должны иметь только одно утверждение (в качестве рекомендации). В результате, когда тест терпит неудачу, вы точно знаете, что не удалось (т. е. inProgress не имеет значение true, завершено отображается несколько раз и т. д.). Вы потенциально получаете гораздо больше (но теоретически более простых и ясных) тестов, например:
[Test] public mustInvokeExecuteForEachQueryTaskWhenQueueIsNotEmpty():void
[Test] public mustBeInProgressWhenResultsArePending():void
[Test] public mustNotInProgressWhenResultsAreProcessedAndSent:void
[Test] public mustDispatchTheCompletedEventWhenAllResultsProcessed():void
[Test] public mustNeverDispatchTheCanceledEventWhenNotCanceled():void
[Test] public mustReturnQueryQueueEventArgsWithResultsAndNoErrorsWhenAllQueriesAreSuccessful:void
// ... and so on
Это может привести к большому количеству повторяющегося кода в тестах, но это можно минимизировать с помощью соответствующих методов setup и teardown.
Хотя этот вопрос похож на другие вопросы, я ищу ответ для этого конкретного сценария, поскольку я думаю, что это хорошее представление сложного сценария модульного тестирования, демонстрирующего несколько состояний и поведения, которые необходимо проверить. Многие другие вопросы, к сожалению, не имеют примеров или примеры не демонстрируют сложное состояние и поведение.