Как проверить юнит логики обратного вызова? - PullRequest
11 голосов
/ 22 августа 2011

Более полный вопрос, учитывая зависимость, которая ожидает обратный вызов в качестве параметра, как мне написать модульный тест, который охватывает логику обратного вызова и все еще удается смоделировать зависимость?

public class DoStuff {
    public void runThis(Runnable callback) {
        // call callback
    }
}

public class ClassUnderTest {
    private DoStuff stuffToDo;

    public void methodUnderTest() {
        this.stuffToDo.runThis(/*a runnable with some logic*/)
    }
}

В приведенном выше примере я бы высмеивал stuffToDo, так как должен проверять вызовы и имитировать выходные данные вызовов методов. Однако насмешка runThis приводит к тому, что логика обратного вызова не проверяется. Кроме того, логика обратного вызова выглядит так, как будто она должна быть закрытой, поэтому я не ожидаю, что она будет проверена напрямую; возможно, это заблуждение с моей стороны.

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

Ответы [ 5 ]

10 голосов
/ 22 августа 2011

Вы не можете в одном тесте.Если вы что-то имитируете, это издевается , что означает, что он может только проверять аргументы и моделировать возвращаемые значения (которые вы конфигурируете в тесте).что использует макет в изоляции.Если вам нужен модульный тест DoStuff, вам не нужно беспокоиться об использовании некоторой реализации обратного вызова, которая может работать или не работать.Вы издеваетесь над обратным вызовом, чтобы вам не приходилось об этом беспокоиться.

Хорошие тесты можно по-прежнему проводить, проверяя код обратного вызова изолированно, и проверяя пользователя обратного вызова изолированно (используямакет для обратного вызова) и, возможно, добавив интеграционный тест для хорошей меры, где вы используете полностью настроенный компонент в целом.

1 голос
/ 22 августа 2011

Здесь в основном вы хотите протестировать класс DoStuff . Это означает, что вам нужно отменить все методы внутри DoStuff, верно? Так что в этом случае вам нужно вместо того, чтобы самим насмехаться над stuffToDo , вводить надуманный Runnable в stuffToDo. И затем проверьте, был ли ваш runnable успешно выполнен или нет.

Но если у вас есть другие функциональные возможности в классе, у вас может быть отдельный тест и макет их.

0 голосов
/ 23 августа 2011

Как насчет фальшивого DoStuff, который просто безоговорочно вызывает Runnable?

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

0 голосов
/ 22 августа 2011

Если вы используете EasyMock, вы можете использовать andStubAnswer для вызова работоспособного.

doSomethingMock.runThis(runnable);
expectLastCall().andStubAnswer(new IAnserable<Void>() {
   Runnable runnable = (Runnable)getCurrentArguments()[0];
   runnable.run();
   return null;
});

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

0 голосов
/ 22 августа 2011

В вашем конкретном случае это звучит так, как будто вы уже протестировали DoStuff (или вам уже все равно, потому что он поиздевался) и теперь специально тестируете юнит для конкретного Runnable, который вы разработали.В этом случае callback звучит как то, что вы хотите тестировать, точно так же, как кто-то может захотеть специально выполнить юнит-тестирование стратегии базы данных или стратегии в памяти.

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

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

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