Я написал фабрику для производства java.sql.Connection
объектов:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
@Override public Connection getConnection() {
try {
return DriverManager.getConnection(...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Я хотел бы проверить параметры, передаваемые DriverManager.getConnection
, но я не знаю, как смоделировать статический метод. Я использую JUnit 4 и Mockito для моих тестовых случаев. Есть ли хороший способ для проверки / проверки этого конкретного варианта использования?
java
unit-testing
mocking
mockito
Нафтули Кей
источник
источник
static
методы насмешки , но случайно . Это ограничение (наряду с отсутствием поддержкиfinal
классов / методовnew
имитации или объектов -ed) является естественным (но непреднамеренным) следствием подхода, применяемого для реализации имитации, когда динамически создаются новые классы, которые реализуют / расширяют тип, подлежащий моделированию; другие библиотеки насмешек используют другие подходы, которые избегают этих ограничений. Это произошло и в мире .NET.Ответы:
Используйте PowerMockito поверх Mockito.
Пример кода:
Больше информации:
источник
@RunWith(PowerMockRunner.class)
и ниже@PowerMockRunnerDelegate(JUnit4.class)
.Типичная стратегия уклонения от статических методов, которую вы никак не можете избежать, заключается в создании обернутых объектов и использовании вместо них объектов-оберток.
Объекты-обертки становятся фасадами реальных статических классов, и вы их не тестируете.
Объект-обертка может быть чем-то вроде
Наконец, ваш тестируемый класс может использовать этот одноэлементный объект, например, имея конструктор по умолчанию для реального использования:
И здесь у вас есть класс, который можно легко протестировать, потому что вы напрямую не используете класс со статическими методами.
Если вы используете CDI и можете использовать аннотацию @Inject, то это еще проще. Просто создайте свой бин Wrapper @ApplicationScoped, добавьте эту штуку в качестве соавтора (вам даже не нужны грязные конструкторы для тестирования) и продолжайте издеваться.
источник
У меня была похожая проблема. Принятый ответ не работал для меня, пока я не сделал изменение:
@PrepareForTest(TheClassThatContainsStaticMethod.class)
согласно документации PowerMock для mockStatic .И я не должен использовать
BDDMockito
.Мои занятия:
Мой тестовый класс:
источник
Как упоминалось ранее, вы не можете издеваться над статическими методами с помощью mockito.
Если вы не можете изменить структуру тестирования, вы можете сделать следующее:
Создайте интерфейс для DriverManager, смоделируйте этот интерфейс, внедрите его посредством какого-либо внедрения зависимостей и проверьте на этом макете.
источник
Замечание: когда вы вызываете статический метод внутри статической сущности, вам нужно изменить класс в @PrepareForTest.
Например:
Для приведенного выше кода, если вам нужно смоделировать класс MessageDigest, используйте
Хотя, если у вас есть что-то вроде ниже:
затем вам нужно подготовить класс, в котором находится этот код.
А затем смоделируйте метод:
источник
Вы можете сделать это с небольшим рефакторингом:
Затем вы можете расширить свой класс,
MySQLDatabaseConnectionFactory
чтобы он возвращал фиктивное соединение, делал утверждения о параметрах и т. Д.Расширенный класс может находиться в тестовом примере, если он находится в том же пакете (что я рекомендую вам сделать)
источник
Для макетирования статического метода вы должны использовать Powermock: https://github.com/powermock/powermock/wiki/MockStatic . Mockito не предоставляет эту функциональность.
Вы можете прочитать хорошую статью о mockito: http://refcardz.dzone.com/refcardz/mockito
источник
Mockito не может захватывать статические методы, но начиная с Mockito 2.14.0 вы можете имитировать его, создавая экземпляры статических методов.
Пример (извлечено из их тестов ):
Их цель не в том, чтобы напрямую поддерживать статический макет, а в том, чтобы улучшить его общедоступные API, чтобы другие библиотеки, такие как Powermockito , не полагались на внутренние API или напрямую дублировали некоторый код Mockito. ( источник )
источник
Я также написал сочетание Mockito и AspectJ: https://github.com/iirekm/varia/tree/develop/ajmock
Ваш пример становится:
источник
Поскольку этот метод является статическим, в нем уже есть все, что вам нужно для его использования, поэтому он побеждает цель насмешки. Насмешка над статическими методами считается плохой практикой.
Если вы попытаетесь это сделать, значит, что с тестированием что-то не так.
Конечно, вы можете использовать PowerMockito или любой другой фреймворк, способный сделать это, но попробуйте переосмыслить свой подход.
Например: попробуйте смоделировать / предоставить объекты, которые использует этот статический метод.
источник
Используйте фреймворк JMockit . Это сработало для меня. Вам не нужно писать операторы для насмешливого метода DBConenction.getConnection (). Достаточно только приведенного ниже кода.
@Mock ниже - пакет mockit.Mock
источник