Java 如何在使用JUnit的DAO层中激发SQLException

Java 如何在使用JUnit的DAO层中激发SQLException,java,junit,code-coverage,dao,sqlexception,Java,Junit,Code Coverage,Dao,Sqlexception,我有一个DAO层,我想用JUnit测试它。测试覆盖率约为85%,因此除了SQLException的catch子句外,几乎每一行代码都被覆盖。我不知道如何引发以下代码段的SQLException: 对我来说,唯一可行的解决方案是将最终变量SELECT\u ALL\u ATTR的值重置为类似于:selllect*FROM ATTRIBUTES使用java反射。我知道我可以通过使用Mock框架轻松地测试异常。但是我不想仅仅为了异常测试而引入模拟测试,因为其他一切都是用JUnit测试的 除了java反

我有一个DAO层,我想用JUnit测试它。测试覆盖率约为85%,因此除了SQLException的catch子句外,几乎每一行代码都被覆盖。我不知道如何引发以下代码段的SQLException:


对我来说,唯一可行的解决方案是将最终变量
SELECT\u ALL\u ATTR
的值重置为类似于:
selllect*FROM ATTRIBUTES使用java反射。我知道我可以通过使用Mock框架轻松地测试异常。但是我不想仅仅为了异常测试而引入模拟测试,因为其他一切都是用JUnit测试的


除了java反射还有其他方法吗?

在您的例子中,模拟sql异常并不容易,因为所有依赖项都是由dao本身启动的。也许您可以传递一个假连接,该连接在某些方法中抛出一个SqlException?

在您的情况下模拟sql异常并不容易,因为所有依赖项都是由dao本身启动的。也许您可以传递一个假连接,该连接在某些方法中抛出SqlException?

这是模拟库的一个很好的用例。我用mockito。假设您想测试DAO客户机的行为,您只需模拟它:

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import junit.framework.Assert;
import org.junit.Test;
public class MockitoTest {
/** your dao, just putting some code here for an example */ 
class MyDAO {
    public List<SVCAttribute> selectAll(Connection con) throws DAOException {
        try {
            //your code..
        }catch(Exception ex) {
            throw new DAOException();
        }
        return new ArrayList<SVCAttribute>();
    }
}
@Test
public void testMe() throws Exception {
    MyDAO dao = mock(MyDAO.class);
    when(dao.selectAll(any(Connection.class))).thenThrow(DAOException.class);
    Connection con = getConnection();
    try {
        dao.selectAll(con);
        Assert.fail();
    }catch(Exception ex) {
        System.out.println("caught expected excetpion");
    }
}
import static org.mockito.Matchers.any;
导入静态org.mockito.mockito.mock;
导入静态org.mockito.mockito.when;
导入junit.framework.Assert;
导入org.junit.Test;
公共类模拟测试{
/**您的dao,在这里放一些代码作为示例*/
类MyDAO{
公共列表selectAll(连接控制)引发异常{
试一试{
//你的代码。。
}捕获(例外情况除外){
抛出新的异常();
}
返回新的ArrayList();
}
}
@试验
public void testMe()引发异常{
MyDAO=mock(MyDAO.class);
当(dao.selectAll(any(Connection.class)))。然后抛出(DAOException.class);
Connection con=getConnection();
试一试{
dao.selectAll(con);
Assert.fail();
}捕获(例外情况除外){
System.out.println(“捕获预期超出”);
}
}

这是模拟库的一个很好的用例。我使用mockito。假设您想测试DAO客户端的行为,您只需模拟它:

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import junit.framework.Assert;
import org.junit.Test;
public class MockitoTest {
/** your dao, just putting some code here for an example */ 
class MyDAO {
    public List<SVCAttribute> selectAll(Connection con) throws DAOException {
        try {
            //your code..
        }catch(Exception ex) {
            throw new DAOException();
        }
        return new ArrayList<SVCAttribute>();
    }
}
@Test
public void testMe() throws Exception {
    MyDAO dao = mock(MyDAO.class);
    when(dao.selectAll(any(Connection.class))).thenThrow(DAOException.class);
    Connection con = getConnection();
    try {
        dao.selectAll(con);
        Assert.fail();
    }catch(Exception ex) {
        System.out.println("caught expected excetpion");
    }
}
import static org.mockito.Matchers.any;
导入静态org.mockito.mockito.mock;
导入静态org.mockito.mockito.when;
导入junit.framework.Assert;
导入org.junit.Test;
公共类模拟测试{
/**您的dao,在这里放一些代码作为示例*/
类MyDAO{
公共列表selectAll(连接控制)引发异常{
试一试{
//你的代码。。
}捕获(例外情况除外){
抛出新的异常();
}
返回新的ArrayList();
}
}
@试验
public void testMe()引发异常{
MyDAO=mock(MyDAO.class);
当(dao.selectAll(any(Connection.class)))。然后抛出(DAOException.class);
Connection con=getConnection();
试一试{
dao.selectAll(con);
Assert.fail();
}捕获(例外情况除外){
System.out.println(“捕获预期超出”);
}
}

我为此写了一个小工具

我为此写了一个小工具

你也应该有否定的测试用例。这些测试用例会覆盖catch块。是的,这就是我想知道的。我如何为这个
selectAll
dao-方法创建这样一个否定的测试用例。方法调用不需要任何参数。让你code
Testable
选择所有属性设置一个getter/setter,而不是将其设置为final(使用默认值)。在否定测试用例中设置不正确的查询。我不喜欢为不应在运行时更改的变量提供setter方法。然后,另一个选项是创建
java.sql.Connection
的虚拟实现,重写方法
prepareStatement
,以返回
PreparedStatement的虚拟实现
。PreparedStatement的虚拟实现具有
executeQueryMethod()
重写为抛出
SQLException
。您也应该有否定的测试用例。这些测试用例将覆盖catch块。是的,这就是我想知道的。如何为这个
selectAll
dao-method创建这样一个否定的测试用例。方法调用不需要任何参数。要使您的代码
可测试
put
的getter/setter选择\u ALL\u ATTR
而不是将其设为final(使用默认值)。在否定测试用例中设置不正确的查询。我不喜欢为不应在运行时更改的变量提供setter方法。然后,另一个选项是创建
java.sql.Connection
的虚拟实现,重写方法
prepareStatement
,以返回
PreparedStatement的虚拟实现
。PreparedStatement的虚拟实现具有
executeQueryMethod()
重写为抛出
SQLException
。此方法工作正常。最初我创建了一个有效连接,但在创建后立即关闭。关闭的连接最终导致SQL异常。此方法工作正常。最初我创建了一个有效连接,但在创建后立即关闭。关闭的连接最终导致这是一个SQL异常。感谢您共享这个非常有用的模块!我还没有尝试过,但它看起来很有希望。感谢您共享这个非常有用的模块!我还没有尝试过,但它看起来很有希望。