¿Cómo puedo probar el código jdbc en java?
database unit-testing (12)
Diría que HSQL es el camino a seguir durante las pruebas de su unidad. El objetivo de tu prueba es probar tu código jdbc y asegurarte de que funciona. Agregar clases personalizadas o burlarse de las llamadas jdbc puede ocultar fácilmente los errores.
Uso principalmente mysql y cuando las pruebas se ejecutan, la clase de controlador y la URL se cambian a org.hsqldb.jdbcDriver y jdbc: hsqldb: mem: test.
Me gustaría escribir algunas pruebas unitarias para algún código que se conecta a una base de datos, ejecuta una o más consultas y luego procesa los resultados. (Sin usar realmente una base de datos)
Otro desarrollador aquí escribió nuestra propia implementación DataSource, Connection, Statement, PreparedStatement y ResultSet que devolverá los objetos correspondientes en base a un archivo de configuración xml. (podríamos usar el origen de datos falso y simplemente ejecutar pruebas contra los conjuntos de resultados que devuelve).
¿Estamos reinventando la rueda aquí? ¿Ya existe algo como esto para las pruebas unitarias? ¿Hay otras / mejores formas de probar el código jdbc?
El controlador Acolyte se puede utilizar para simular una conexión JDBC, administrarla durante las pruebas y devolver datos como conjunto de resultados (con su API de lista de filas segura): https://github.com/cchantep/acolyte
Hay dbunit.org . No le permitirá probar su código jdbc sin una base de datos, pero parece que podría introducir un conjunto diferente de compras emulando una base de datos.
Me gusta usar una combinación de:
- DBUnit
- HSQLDB
- Unitils (específicamente, los módulos de prueba y mantenimiento de la base de datos )
Puede llegar bastante lejos con solo DBUnit y HSQLDB. Unitils proporciona la última milla de código para administrar y restablecer el estado de la base de datos. También proporciona una forma agradable de gestionar los cambios en el esquema de la base de datos y facilita el uso de RBDMS específicos (Oracle, DB2, SQL Server, etc.). Finalmente, Unitils proporciona algunas envolturas agradables alrededor de DBUnit que moderniza la API y hace que DBUnit sea mucho más agradable para trabajar.
Si aún no ha revisado Unitils, definitivamente debería hacerlo. Unitils a menudo es pasado por alto y subestimado.
Prefiero usar EasyMock para probar un código que no es tan fácil de probar .
Si bien la forma de simular jdbc en su aplicación depende, por supuesto, de cómo haya implementado sus transacciones jdbc reales.
Si está utilizando jdbc como está, supongo que se ha escrito una clase de utilidad para hacer algunas tareas en la línea de DBUtils.getMetadataFor(String tablename)
. Lo que esto significa es que tendrías que crear un simulacro de esa clase y eso podría ser todo lo que necesitas. Esta sería una solución bastante fácil para usted, ya que aparentemente ya tiene disponibles una serie de objetos falsos relacionados con jdbc. Tenga en cuenta que supongo que su código jdbc no se ha explotado en toda la aplicación, si es así, ¡refactorícese!
Sin embargo, si está utilizando cualquier marco para el manejo de la base de datos (como las clases de plantilla JDBC de Spring Framework), puede y debe simular la clase de interfaz con EasyMock u otro equivalente. De esta forma, puede tener todo el poder del mundo requerido para burlarse fácilmente de la conexión.
Y por último, si nada funciona, puede hacer lo que otros ya han dicho y usar DBUnit y / o derby.
Si quieres hacer pruebas unitarias, no pruebas de integración, entonces puedes usar un enfoque muy básico y simple, usando solo Mockito, así:
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''s 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);
}
}
Que puede probar varios escenarios, como en cualquier otra prueba de Mockito, por ejemplo
@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));
}
Tienes varias opciones:
- Simula la base de datos con una biblioteca Mock, por ejemplo, JMock . El gran inconveniente de esto es que sus consultas y los datos probablemente no serán probados en absoluto.
- Use una base de datos ligera para las pruebas, como HSQLDB . Si sus consultas son simples, esta es probablemente la forma más fácil de hacerlo.
- Dedique una base de datos para las pruebas. DBUnit es una buena opción, o si está utilizando Maven, también puede usar el sql-maven-plugin para configurar y destruir la base de datos correctamente (tenga cuidado con las dependencias entre las pruebas). Recomiendo esta opción, ya que le dará la mayor seguridad de que las consultas funcionan correctamente con su proveedor de db.
A veces es necesario y útil hacer estas pruebas configurables de modo que estas pruebas solo se ejecuten si la base de datos está disponible. Esto se puede hacer con, por ejemplo, propiedades de compilación.
Usamos Mockrunner. http://mockrunner.sourceforge.net/ Tiene conexiones simuladas y fuentes de datos integradas por lo que no hay necesidad de implementarlas.