#java #unit-testing #junit #dependency-injection
#java #модульное тестирование #junit #внедрение зависимостей
Вопрос:
Я пытаюсь создать библиотеку подключения к базе данных, которая будет использоваться во всех моих приложениях. Я хочу убедиться, что эта библиотека полностью протестирована по модулю, и поэтому я пытаюсь использовать внедрение зависимостей.
У меня есть этот класс, который я хочу убедиться, что он протестирован:
public class ConnectionFactory {
private String dataSourceName;
public ConnectionFactory(String dataSourceName) {
if(dataSourceName == null) {
throw new NullPointerException("dataSourceName can't be null");
}
this.dataSourceName = dataSourceName;
}
public Connection getConnection() throws SQLException {
Connection connection = getDataSource(dataSourceName).getConnection();
if(connection != null) {
return connection;
}
...
}
// Get a datasource object
private DataSource getDataSource(String dataSourceName) {
...
try {
Context ctx = new InitialContext();
dataSource = (DataSource) ctx.lookup("java:comp/env/" dataSourceName);
} catch (NamingException e) {
...
}
return dataSource;
}
}
Я хочу иметь возможность просто вызывать этот класс из всех моих приложений с помощью чего-то такого простого, как это:
public class MyApp {
public static void main(string[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory("jdbc/myDataSource");
Connection connection = connectionFactory.getConnection();
}
}
Я начал писать модульные тесты для этого ConnectionFactory, но быстро понял, что с моим текущим кодом я не могу имитировать объект DataSource, поэтому он пытается фактически подключиться к реальному источнику данных.
@RunWith(Nested.class)
public class ConnectionFactoryTest {
public class Constructor {
@Test
public void shouldThrowNullPointerIfParamIsNull() {
assertThatExceptionOfType(NullPointerException.class)
.isThrownBy(() -> { new ConnectionFactory(null); })
.withMessage("dataSourceName can't be null");
}
}
public class GetConnection {
public class WithDataSourceAvailable {
@Test
public void shouldErrorIfParamIsNull() {
ConnectionFactory connectionFactory = new ConnectionFactory("jdbc/myDataSource"); // <-- This is going to fail b/c it's trying to actually fetch a real data source
}
}
}
}
Как я могу правильно использовать внедрение зависимостей, чтобы я мог писать модульные тесты, которые на самом деле не пытаются подключиться к источнику данных?
Комментарии:
1. «Я не могу издеваться над объектом источника данных» это утверждение неверно. Можно имитировать создание объекта с помощью таких инструментов, как PowerMock.
2. «Я не могу издеваться» означает, что я не знаю, как это издеваться.
Ответ №1:
Взгляните на Mockito, я нахожу его простым в использовании для такого типа макетирования.