[英]testing a delete method in jUnit using jdbcTemplate and DAO Layer
我正在尝试测试我的删除方法,但我不知道该怎么做,我尝试在我的测试删除方法中调用我删除的用户ID的searchByID来创建一个空变量,然后使用assertNull
像这样:
@Test
public void deleteUser()
{
userDAO.deleteUserById(3);
User nullUser = userDAO.searchUserById(3);
assertNull(nullUser);
}
但这给了我这个错误:
expected null but was domain.User@c506pb
我尝试使用异常方法,因为我可以在输出中该代码生成java.sql.SQLException: ORA-01403: no data found
我这样尝试:
@Test(expected=SQLException.class)
public void deleteUser()
{
userDAO.deleteUserById(3);
Usuario usuarioVacio = usuarioDAO.buscarUsuarioPorId(3);
}
但这给了我这个错误:
Expected exception: java.sql.SQLException
java.lang.AssertionError
这是我的删除方法的实现
@Override
public void deleteUserById(int idUser)
{
Connection connection = null;
try {
String storedProcedure = "{ call deleteUserById(?) }";
connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(storedProcedureBorrarUSuario);
callableStatement.setInt(1, idUser);
callableStatement.executeQuery();
}
catch (SQLException ex)
{
ex.printStackTrace();
}
finally
{
if(connection != null)
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
该方法有效,因为它删除了正确的用户,我想使用异常方法和另一种方法来做,但是我不知道为什么不起作用
编辑:
这是我的searchById方法
@Override
public Usuario buscarUsuarioPorId(int userId)
{
User user= new User();
Connection connection = null;
try {
String storedProcedureInfoUsuario = "{ call searchUserById(?, ?, ?, ?, ?) }";
connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(storedProcedureInfoUsuario);
callableStatement.setInt(1, idUsuario);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.registerOutParameter(3, Types.VARCHAR);
callableStatement.registerOutParameter(4, Types.VARCHAR);
callableStatement.registerOutParameter(5, Types.VARCHAR);
callableStatement.executeQuery();
//
user.setName(callableStatement.getString(2));
user.setLastName(callableStatement.getString(3));
user.setEmail(callableStatement.getString(4));
user.setState(callableStatement.getString(5));
}
catch (SQLException ex)
{
// Logger.getLogger(UsuarioDAOImplementacion.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
finally
{
if(connection != null)
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
return usuario;
}
这是我的PL / SQL searchById
CREATE OR REPLACE PROCEDURE searchUserById
(
p_userId IN User.user_id%TYPE,
ps_name OUT User.name%TYPE,
ps_lastName OUT User.lastName%TYPE,
ps_email OUT User.email%TYPE,
ps_state OUT User.state%TYPE
)
IS
BEGIN
SELECT name, lastName, email, state
INTO ps_name , ps_lastName , ps_email , ps_state
FROM USER WHERE user_id= p_userid;
END;
/
这是我的删除PL / SQL
CREATE OR REPLACE PROCEDURE deleteUserById
(
p_userId IN USER.user_ID%TYPE
)
IS
BEGIN
DELETE FROM USER
WHERE user_id=p_userId;
COMMIT;
END;
/
编辑2
我创建了这个建议的方法,但它给了我一个错误,我缺少返回值,所以我添加了return null
@Override
public void deleteUserById(final int idUser) {
final String storedProcedureBorrarUSuario = "{ call borrarUsuarioPorId(?) }";
final Connection connection = null;
jdbcTemplate.execute( new ConnectionCallback<Object>()
{
@Override
public Object doInConnection(Connection con) throws SQLException, DataAccessException
{
CallableStatement callableStatement = connection.prepareCall(storedProcedureBorrarUSuario);
callableStatement.setInt(1, idUser);
callableStatement.executeUpdate();
return null;
}
});
}
当我运行我的单元测试时,它在这一行说空指针异常
userDAO.deleteUserById(3);
编辑3
我尝试使用此设置将用户设置为null,因此如果出现异常,我的方法将返回null对象,但是当我尝试使用异常方法时,我的单元测试中仍然存在相同的问题
@Override
public Usuario searchUserById(int userId)
{
User user= null;
Connection connection = null;
try {
String storedProcedureInfoUsuario = "{ call searchUserById(?, ?, ?, ?, ?) }";
connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(storedProcedureInfoUsuario);
callableStatement.setInt(1, userId);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.registerOutParameter(3, Types.VARCHAR);
callableStatement.registerOutParameter(4, Types.VARCHAR);
callableStatement.registerOutParameter(5, Types.VARCHAR);
callableStatement.executeQuery();
//
user= new User();
usuario.setName(callableStatement.getString(2));
usuario.setLastName(callableStatement.getString(3));
usuario.setEmail(callableStatement.getString(4));
usuario.setState(callableStatement.getString(5));
}
catch (SQLException ex)
{
// Logger.getLogger(UsuarioDAOImplementacion.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
finally
{
if(connection != null)
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
return user;
}
这是我的单元测试,我希望有一个空值,这可以与我所做的修改一起使用
public void findUserById()
{
User emptyUser= userDAO.searchUserById(50);
assertNull(emptyUser);
}
但是,如果我尝试使用异常方法,则会出现以下错误
@Test(expected=SQLException.class)
public void findUserById()
{
User emptyUser= userDAO.searchUserById(50);
assertNull(emptyUser);
}
这给了我Expected exception: java.sql.SQLException java.lang.AssertionError
我不知道为什么如果我的输出java.sql.SQLException: ORA-01403: no data found
存在以下异常,这将不起作用java.sql.SQLException: ORA-01403: no data found
问题出在您的方法serachUserById()上。 我在下面的代码中为您修复了该问题。 您总是返回一个用户对象。 无论数据库中是否有用户。 下面的代码首先为用户分配null。 我想如果没有使用该userId的用户,就会有一个例外。 因此,您捕获了异常并继续返回null。 如果数据库中有一个用户,则将创建一个User对象,将其填充值并返回该对象。
关键是要区分1。有一个用户,我用User对象返回它; 2。没有用户,我返回null。
@Override
public User serachUserById(int userId)
{
User user = null;
Connection connection = null;
try {
String storedProcedureInfoUsuario = "{ call searchUserById(?, ?, ?, ?, ?) }";
connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(storedProcedureInfoUsuario);
callableStatement.setInt(1, userId);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.registerOutParameter(3, Types.VARCHAR);
callableStatement.registerOutParameter(4, Types.VARCHAR);
callableStatement.registerOutParameter(5, Types.VARCHAR);
callableStatement.executeQuery();
//
user = new User();
user.setName(callableStatement.getString(2));
user.setLastName(callableStatement.getString(3));
user.setEmail(callableStatement.getString(4));
user.setState(callableStatement.getString(5));
}
catch (SQLException ex)
{
Logger.getLogger(UsuarioDAOImplementacion.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
finally
{
if(connection != null)
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
return user;
}
无论如何,我建议您使用Spring JPA存储库,而不要使用JDBC连接,SQL和存储过程。 您将节省大量时间和错误。
可能存在以下可能性
您的PL / SQL中有问题。 看到何时收到该异常? 在删除用户或搜索用户时。
在测试上下文的事务配置中为defaultRollback设置的配置值是什么? 如果确实如此,则意味着您的更改将在执行测试方法后回滚,这就是为什么您可能会在搜索用户中获得价值的原因
如果其他一切都没问题,那么可能存在事务边界问题。
首先,我建议您重写JDBC代码并实际使用JdbcTemplate
。 不用自己管理连接,而是将逻辑包装在ConnectionCallback
可以避免打开/关闭连接。
其次,您应该使用executeUpdate
ins进行修改
@Override
public void deleteUserById(final int idUser) {
final String storedProcedure = "{ call deleteUserById(?) }";
getJdbcTemplate().execute(new ConnectionCallback<Object>() {
public Object doInConnection(Connection con) throws SQLException, DataAccessException {
CallableStatement callableStatement = con.prepareCall(storedProcedureBorrarUSuario);
callableStatement.setInt(1, idUser);
callableStatement.executeUpdate();
return null;
}
});
}
@Override
public Usuario buscarUsuarioPorId(final int userId) {
User user= new User();
final String storedProcedureInfoUsuario = "{ call searchUserById(?, ?, ?, ?, ?) }";
return getJdbcTemplate().execute(new ConnectionCallback<User>() {
public User doInConnection(Connection con) throws SQLException, DataAccessException {
CallableStatement callableStatement = con.prepareCall(storedProcedureInfoUsuario);
callableStatement.setInt(1, idUsuario);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.registerOutParameter(3, Types.VARCHAR);
callableStatement.registerOutParameter(4, Types.VARCHAR);
callableStatement.registerOutParameter(5, Types.VARCHAR);
callableStatement.executeQuery();
//
user.setName(callableStatement.getString(2));
user.setLastName(callableStatement.getString(3));
user.setEmail(callableStatement.getString(4));
user.setState(callableStatement.getString(5));
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.