I've begun learning unit tests. I'm trying to write some tests using Junit5 and Mockito for my DAO's. And I need help, what next I need. How should I test it ?
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class RecipeDao {
private static final String CREATE_RECIPE_QUERY = "INSERT INTO " +
"recipe(name, ingredients, description, created, preparation_time, preparation, admin_id)" +
"VALUES (?,?,?,?,?,?,?)";
/**
* Create recipe
*
* @param recipe object
* @return created Recipe in db
*/
public Recipe create(Recipe recipe) {
try (Connection connection = DbUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(CREATE_RECIPE_QUERY,
PreparedStatement.RETURN_GENERATED_KEYS)
) {
statement.setString(1, recipe.getName());
statement.setString(2, recipe.getIngredients());
statement.setString(3, recipe.getDescription());
statement.setString(4, currentTime());
statement.setInt(5, recipe.getPreparationTime());
statement.setString(6, recipe.getPreparation());
statement.setInt(7,recipe.getAdminId());
int result = statement.executeUpdate();
if (result != 1) {
throw new RuntimeException("Execute update returned " + result);
}
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.first()) {
recipe.setId(generatedKeys.getInt(1));
return recipe;
} else {
throw new RuntimeException("Generated key was not found");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
I write class DbUtil to connecting in database.
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DbUtil {
private static DataSource dataSource;
public static Connection getConnection() throws SQLException {
return getInstance().getConnection();
}
private static DataSource getInstance() {
if (dataSource == null) {
try {
Context context = new InitialContext();
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/scrumlab");
} catch (NamingException e) {
e.printStackTrace();
}
}
return dataSource;
}
}
I don't know how prepare connection to database used Mockito. I tried as below. But I don't know if I'm using @Mock correctly.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.internal.util.reflection.Fields;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
class RecipeDaoTest {
@InjectMocks
private RecipeDao recipeDao;
@Mock
DataSource mockDataSource;
@Mock
Connection mockConn;
@Mock
PreparedStatement mockPreparedStmnt;
@Mock
ResultSet mockResultSet;
public RecipeDaoTest() {
}
@BeforeEach
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);
}
@org.junit.jupiter.api.Test
void create() {
}
}
Is it correct way to test it?