Модульные тесты в Groovy для кода Java - как издеваться над классами Java?
Я представляю Groovy в большом проекте, написанном на Java, начиная (как это делают большинство парней) с написания модульного теста в Groovy для классов Java.
Итак, у меня есть проблема:
Представьте, что у меня есть 2 Java-класса, ClassA и ClassB, которые взаимодействуют следующим образом:
public class ClassA {
public void doSomething(...) {
...//something
ClassB.invokeSomeStaticMethod((someParam);
...//something
}
}
ClassB - сервис, ищущий некоторые данные из базы данных. Я тестирую функциональность ClassA. Так что я хотел бы каким-то образом смоделировать ClassB, так что invokeSomeStaticMethod() в контексте моего модульного теста вернул бы проверенное значение для тестирования. Насколько я понимаю, основная проблема здесь в том, что оба класса являются Java, и, следовательно, метод ClassB.invoke... не маршрутизируется через Groovy MOP, на котором основаны Groovy Mocks. Я прав? И как я могу достичь того, что мне нужно?
Спасибо! Михаил
3 ответа
AFAIK, Groovy MOP не сможет заменить звонок ClassB.invokeSomeStaticMethod(someParam)
, Вы можете использовать фреймворк, такой как JMockit, чтобы помочь вам высмеивать статический метод.
Статические методы, такие как синглтоны, являются смертью для тестируемости. Хотя в динамических языках, таких как Groovy, это немного меньше, конечно, вы столкнулись с классической проблемой тестируемости.
Решение состоит в том, чтобы экстернализировать вашу зависимость и удалить статический метод из ClassB
public class ClassA(ClassB classB)
{
ClassB classB
public void doSomething()
{
classB.invokeSomething();
}
}
Этот подход имеет два преимущества:
ClassA
Nolonger тесно связан сClassB
, Его можно заменить на подкласс или макет.ClassA
теперь рекламирует свою зависимость отClassB
чтобы весь мир знал, а не полагаться на ошибки времени выполнения, чтобы разработчики знали, что чего-то не хватает.
Отличная статья Singletons are Liars (из блога Google Testing) отлично справляется с изучением этой концепции.
Ну, я думаю, что метапрограммирование может помочь, но как только ClassB вызывается из кода Java, его метакласс не будет работать.