unitarios test how examples ejemplo java unit-testing junit mockito dao

how - test unitarios java mockito



¿Cómo probar los métodos DAO usando Mockito? (4)

Pero, ¿y si también quiero probar el comportamiento de dao y la base de datos?

Si realmente desea probar la base de datos (¡como debería!), No hay forma de evitarla: necesita una base de datos real. Mockito, aunque es una gran biblioteca, es probablemente la herramienta incorrecta para este trabajo.

Empecé a descubrir la biblioteca de Mockito y hay una pregunta para la que no encontré la respuesta correcta.

Si tengo, por ejemplo, un método de este tipo en mi clase UserDAO que guarda al usuario en la base de datos:

public class UserDAO{ ... public void create(User user) { Connection connection = null; PreparedStatement pstmt = null; ResultSet generatedKeys = null; try { connection = getConnection(); pstmt = connection.prepareStatement(INSERT_USER, PreparedStatement.RETURN_GENERATED_KEYS); int counter = 1; pstmt.setString(counter++, user.getFirstName()); pstmt.setString(counter++, user.getLastName()); pstmt.setString(counter++, user.getEmail()); pstmt.setString(counter++, user.getPassword()); pstmt.setString(counter++, user.getRole()); pstmt.setString(counter, user.getLang()); pstmt.execute(); connection.commit(); generatedKeys = pstmt.getGeneratedKeys(); if (generatedKeys.next()) { user.setId(generatedKeys.getInt(Fields.GENERATED_KEY)); } } catch (SQLException e) { rollback(connection); LOG.error("Can not create a user", e); } finally { close(connection); close(pstmt); close(generatedKeys); } } .... }

¿Cómo debo probarlo?

Si quiero probar, por ejemplo, una clase DAO, entonces necesito crear un simulacro de DataSource , un simulacro de Connection , un simulador de ResultSet , etc. ¿Y entonces no para probar la propia base de datos?

Pero, ¿y si también quiero probar el comportamiento de dao y la base de datos?

¿Podría, por favor, producir algunos ejemplos de código, enlaces que podrían ser útiles y mostrar los mejores métodos para hacerlo?


Aquí es cómo debe probarlo:

public class UserDAOTest extends IntegrationTests { // Or do it in a @Before method, if needed. UserDAO dao = new UserDAO(); @Test public void createValidUser() { User validUser = new User( "John", "Smith", "[email protected]", "Abc123!@", "admin", "en"); // or use setters as needed dao.create(validUser); assertEntityCreatedInDB(validUser); } @Test public void attemptToCreateInvalidUser() { User invalidUser = new User("", null, null, "", null, "XY"); dao.create(invalidUser); // This really shouldn''t be done this way, as DAOs are not supposed // to manage transactions; instead, a suitable, descriptive // exception should be thrown by the DAO and checked in the test. assertTransactionWasRolledBack(); } }

Un par de notas sobre lo anterior:

1) Las pruebas parecen cortas, simples y fáciles de entender, como deberían ser ; Si se ven grandes y feos como los de otra respuesta, estás haciendo algo fundamentalmente incorrecto.

2) El código de prueba puede y debe tener sus propios ayudantes de infraestructura, como la clase base IntegrationTests , que ocultará cualquier acceso JDBC / ORM desagradable de las pruebas reales. Implementé tales ayudantes en varios proyectos, así que sé que esto se puede hacer, pero eso sería algo para otras preguntas.


Aquí es un buen comienzo usando Mockito para probar su UserDAO. Este código utiliza una buena cantidad de funciones de Mockito, por lo que puede ver cómo usarlas. Si tienes preguntas, déjamelo saber.

import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import org.junit.runner.RunWith; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import org.mockito.Mock; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class TestUserDAO { @Mock DataSource mockDataSource; @Mock Connection mockConn; @Mock PreparedStatement mockPreparedStmnt; @Mock ResultSet mockResultSet; int userId = 100; public TestUserDAO() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() { } @Before public void setUp() throws SQLException { when(mockDataSource.getConnection()).thenReturn(mockConn); when(mockDataSource.getConnection(anyString(), anyString())).thenReturn(mockConn); doNothing().when(mockConn).commit(); when(mockConn.prepareStatement(anyString(), anyInt())).thenReturn(mockPreparedStmnt); doNothing().when(mockPreparedStmnt).setString(anyInt(), anyString()); when(mockPreparedStmnt.execute()).thenReturn(Boolean.TRUE); when(mockPreparedStmnt.getGeneratedKeys()).thenReturn(mockResultSet); when(mockResultSet.next()).thenReturn(Boolean.TRUE, Boolean.FALSE); when(mockResultSet.getInt(Fields.GENERATED_KEYS)).thenReturn(userId); } @After public void tearDown() { } @Test public void testCreateWithNoExceptions() throws SQLException { UserDAO instance = new UserDAO(mockDataSource); instance.create(new User()); //verify and assert verify(mockConn, times(1)).prepareStatement(anyString(), anyInt()); verify(mockPreparedStmnt, times(6)).setString(anyInt(), anyString()); verify(mockPreparedStmnt, times(1)).execute(); verify(mockConn, times(1)).commit(); verify(mockResultSet, times(2)).next(); verify(mockResultSet, times(1)).getInt(Fields.GENERATED_KEYS); } @Test(expected = SQLException.class) public void testCreateWithPreparedStmntException() throws SQLException { //mock when(mockConn.prepareStatement(anyString(), anyInt())).thenThrow(new SQLException()); try { UserDAO instance = new UserDAO(mockDataSource); instance.create(new User()); } catch (SQLException se) { //verify and assert verify(mockConn, times(1)).prepareStatement(anyString(), anyInt()); verify(mockPreparedStmnt, times(0)).setString(anyInt(), anyString()); verify(mockPreparedStmnt, times(0)).execute(); verify(mockConn, times(0)).commit(); verify(mockResultSet, times(0)).next(); verify(mockResultSet, times(0)).getInt(Fields.GENERATED_KEYS); throw se; } } }


Una herramienta como DBUnit combinada con JUnit podría ayudarlo a probar sus DAO con la base de datos. DBUnit lo ayuda a insertar datos de prueba en la base de datos antes de su UnitTest y comparar los datos en la base de datos con sus expectativas después de la prueba.