Ответ 1
Вы можете использовать DBUnit вместе с HSQLDB, который может читать свои исходные данные из файлов CSV, например.
Я хотел бы написать некоторые модульные тесты для некоторого кода, который подключается к базе данных, запускает один или несколько запросов и затем обрабатывает результаты. (Без фактического использования базы данных)
Другой разработчик написал нашу собственную реализацию DataSource, Connection, Statement, PreparedStatement и ResultSet, которая вернет соответствующие объекты на основе файла конфигурации xml. (мы могли бы использовать фиктивный источник данных и просто запускать тесты с возвращаемыми наборами результатов).
Мы изобретаем колесо здесь? Что-то подобное уже существует для модульного тестирования? Существуют ли другие/лучшие способы тестирования кода jdbc?
Вы можете использовать DBUnit вместе с HSQLDB, который может читать свои исходные данные из файлов CSV, например.
У вас есть несколько вариантов:
Иногда бывает необходимо и полезно сделать эти тесты настраиваемыми, чтобы эти тесты выполнялись только в том случае, если база данных доступна. Это может быть выполнено, например, строить свойства.
Мне нравится использовать комбинацию:
Вы можете получить довольно далеко с DBUnit и HSQLDB. Unitils предоставляет последнюю милю кода для управления и состояние базы данных reset. Он также обеспечивает хороший способ управления изменениями схемы базы данных и упрощает использование определенных RBDMS (Oracle, DB2, SQL Server и т.д.). Наконец, Unitils предоставляет несколько хороших оберток вокруг DBUnit, который модернизирует API и упрощает работу с DBUnit.
Если вы еще не проверили Unitils, вам обязательно нужно. Унилиды часто упускают из виду и недооценивают.
Используйте любую из фреймворков Mock для такой задачи. (jMock, и т.д..
Некоторые примеры
Вот почему у вас derby (теперь называется JavaDB) или sqlite - это небольшие, простые базы данных, которые вы можете создавать, загружать, тестировать и уничтожать относительно быстро и просто.
Я бы сказал, что HSQL - это способ пойти во время модульных тестов. Цель вашего теста - проверить ваш код jdbc и убедиться, что он работает. Добавление пользовательских классов или издевательство над вызовами jdbc может скрыть ошибки.
В основном я использую mysql, и когда тесты запускают класс драйвера, а url изменяется на org.hsqldb.jdbcDriver и jdbc: hsqldb: mem: test.
Я предпочитаю использовать EasyMock для тестирования кода, который не очень прост в тестировании.
Существует DBUnit. Это не позволит вам протестировать ваш код jdbc без базы данных, но похоже, что вы можете ввести другой набор покупок, эмулируя базу данных.
Хотя способ издеваться над jdbc в вашем приложении, конечно, зависит от того, как вы реализовали свои фактические транзакции jdbc.
Если вы используете jdbc как есть, я бы предположил, что вы написали себе класс утилиты для выполнения некоторых задач в строке DBUtils.getMetadataFor(String tablename)
. Это будет означать, что вам нужно будет создать макет этого класса, и это может быть все, что вам нужно. Это было бы довольно простое решение для вас, поскольку у вас, видимо, уже есть серия связанных с jdbc макетных объектов. Обратите внимание, что я предполагаю, что ваш код jdbc не разрывается вокруг приложения - если это так, рефакторинг!!!
Если вы используете какую-либо инфраструктуру для обработки базы данных (например, Spring Framework JDBC Template classes), вы можете и должны высмеять класс интерфейса с помощью EasyMock или другого эквивалента. Таким образом, вы можете иметь всю силу в мире, необходимую для легкой насмешки соединения.
И последнее, если ничего не работает, вы можете сделать то, что уже сказали другие, и использовать DBUnit и/или дерби.
Если вы хотите выполнять модульные тесты, а не тесты интеграции, то вы можете использовать очень простой и простой подход, используя только Mockito, например:
public class JDBCLowLevelTest {
private TestedClass tested;
private Connection connection;
private static Driver driver;
@BeforeClass
public static void setUpClass() throws Exception {
// (Optional) Print DriverManager logs to system out
DriverManager.setLogWriter(new PrintWriter((System.out)));
// (Optional) Sometimes you need to get rid of a driver (e.g JDBC-ODBC Bridge)
Driver configuredDriver = DriverManager.getDriver("jdbc:odbc:url");
System.out.println("De-registering the configured driver: " + configuredDriver);
DriverManager.deregisterDriver(configuredDriver);
// Register the mocked driver
driver = mock(Driver.class);
System.out.println("Registering the mock driver: " + driver);
DriverManager.registerDriver(driver);
}
@AfterClass
public static void tearDown() throws Exception {
// Let cleanup the global state
System.out.println("De-registering the mock driver: " + driver);
DriverManager.deregisterDriver(driver);
}
@Before
public void setUp() throws Exception {
// given
tested = new TestedClass();
connection = mock(Connection.class);
given(driver.acceptsURL(anyString())).willReturn(true);
given(driver.connect(anyString(), Matchers.<Properties>any()))
.willReturn(connection);
given(connection.prepareCall(anyString())).willReturn(statement);
}
}
Чем вы можете протестировать различные сценарии, например, в любом другом тесте Mockito, например.
@Test
public void shouldHandleDoubleException() throws Exception {
// given
SomeData someData = new SomeData();
given(connection.prepareCall(anyString()))
.willThrow(new SQLException("Prepare call"));
willThrow(new SQLException("Close exception")).given(connection).close();
// when
SomeResponse response = testClass.someMethod(someData);
// then
assertThat(response, is(SOME_ERROR));
}
Мы используем Mockrunner. http://mockrunner.sourceforge.net/ Он содержит ложные соединения и источники данных, поэтому нет необходимости реализовывать их сами.
Драйвер Acolyte может использоваться для моделирования соединения JDBC, управления им во время тестов и возврата данных в виде набора результатов (с его API-интерфейсом типов со списком строк): https://github.com/cchantep/acolyte