有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java你能解释一下异常是如何在测试用例中可用的吗?

有一个关于检查Junits中已处理异常的问题。我似乎在我的代码中做到了这一点。其他人倾向于说这是不可能的,因为异常不是由该方法引发的。有人能解释一下下面的代码中发生了什么吗

public class DatabaseConnector
{

private DBConnectionInfo dbObject;
private DBQueryStatements dbQueries;

void loadConnectionInfo()
{
    Properties databaseProperties = new Properties();
    try
    {
        databaseProperties.load(getClass().getClassLoader().getResourceAsStream("database.properties"));
        dbObject.setDatabaseURL(databaseProperties.getProperty("jdbc.url"));
        dbObject.setUserName(databaseProperties.getProperty("jdbc.username"));
        dbObject.setPassword(databaseProperties.getProperty("jdbc.password"));
        dbObject.setDriver(databaseProperties.getProperty("jdbc.driver"));
    } catch (IOException e)
    {

        Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
        lgr.log(Level.SEVERE, e.getMessage(), e);
    }

}

public DBConnectionInfo connectionInit()
{

    loadConnectionInfo();

    try
    {
        Class.forName(dbObject.getDriver());
    } catch (Exception e)
    {
        Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
        lgr.log(Level.SEVERE, e.getMessage(), e);
    }

    try
    {
        dbObject.setConnection(DriverManager.getConnection(dbObject.getDatabaseURL(), dbObject.getUserName(),
                dbObject.getPassword()));
    } catch (Exception e)
    {
        Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
        lgr.log(Level.SEVERE, e.getMessage(), e);
    }
    return dbObject;
}
}

以上代码的测试用例

public class DatabaseConnectorTest
{

DatabaseConnector dbConnector;
DBConnectionInfo dbModelObject;
DBQueryStatements dbQueries;

    @Before
    public void setUp() throws Exception
    {
        MockitoAnnotations.initMocks(this);
        dbModelObject = mock(DBConnectionInfo.class);
        dbQueries = mock(DBQueryStatements.class);    
        dbConnector = new DatabaseConnector(dbModelObject,dbQueries);
    }

@Test
public void testDriverFailure()
{
    when(dbModelObject.getDriver()).thenReturn("driver");
    when(dbModelObject.getDatabaseURL()).thenReturn("jdbc:postgresql://127.0.0.1:5432/testdb");
    when(dbModelObject.getUserName()).thenReturn("postgres");
    when(dbModelObject.getPassword()).thenReturn("postgres");

    try
    {
        dbConnector.connectionInit();
    } catch (Exception e)
    {
        assertTrue(e instanceof ClassNotFoundException);
    }

    verify(dbModelObject).getDriver();
}

@Test
public void testConnectionFailure()
{
    when(dbModelObject.getDriver()).thenReturn("org.postgresql.Driver");
    when(dbModelObject.getDatabaseURL()).thenReturn("jdbc:postgresql://127.0.0.1:5432/testdb");
    when(dbModelObject.getUserName()).thenReturn("uname");
    when(dbModelObject.getPassword()).thenReturn("uname");
    try
    {
        dbConnector.connectionInit();
    } catch (Exception e)
    {
        assertTrue(e instanceof SQLException);
    }

    verify(dbModelObject).getDriver();
    verify(dbModelObject).getDatabaseURL();
    verify(dbModelObject).getUserName();
    verify(dbModelObject).getPassword();
}
}

共 (3) 个答案

  1. # 1 楼答案

    在代码中捕获异常,并在日志中写入内容。因此,测试无法看到异常,您也无法测试它是否被抛出。但是你可以测试你是否记录了一些东西。另一种方法是测试代码是否不会引发异常并返回null

  2. # 2 楼答案

    当前编写的方法connectionInit ()不会引发任何异常。在这两个测试用例中,您都应该检查预期的失败(根据我对代码的理解),但如果没有失败发生,您就不会调用fail ()JUnit方法,因此您的测试用例都通过了,而它们都应该失败。正如Mirko提到的,在调用connectionInit ()之后,应该将代码更改为调用fail ()

  3. # 3 楼答案

    只需使用@Test注释即可

    @Test(预期=RuntimeException.class)

    另一个解决方案是,当你期望出现异常时,你应该让你的测试失败

    @Test
    public void testConnectionFailure()
    {
        ...
        try
        {
            dbConnector.connectionInit();
            fail("an exception should be thrown...")
        } catch (Exception e)
        {
            assertTrue(e instanceof SQLException);
        }
        ...
    }  
    

    更新#1:

    我认为你的代码和测试用例不是很好,因为在你的代码中你捕捉到了所有“好”的异常!但他们会告诉你哪里出了问题

    所以让你的代码抛出这些异常

    但另一方面是:为什么要为标准javajava编写测试用例。sql功能(类加载、DriverManager)

    更新#2:

    我会用你的例子来解释,因为我不是英国人

    您的代码:

    try
    {
            Class.forName(dbObject.getDriver());  
    } catch (Exception e)
    {
            Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
            lgr.log(Level.SEVERE, e.getMessage(), e);
    }
    

    您的文字代码:

    try
    {
            Do something from java standard. //Class.forName(dbObject.getDriver());  
    } if an exception occures, go in this block //catch (Exception e) 
    {
            Just print out the exception. 
            If someone knowns about your application he'll take a look in the log. 
            If not, your exception is lost, after leaving this block.
            And I think here is your problem!
            Do not catch any exceptions in a so low level of your application.
    }
    

    您的测试用例:

    @Test
    public void testDriverFailure()
    {
        ....
        try
        {
            dbConnector.connectionInit();
        } catch (Exception e)
        {
            assertTrue(e instanceof ClassNotFoundException);
        }
    }
    

    您的测试用例:

    @Test
    public void testDriverFailure()
    {
        ....
        try
        {
            try to init your dbConnector. 
        } Catch exceptions (
              They never thrown, because you already catched them in the method connectionInit().
              And here right now, you know, why its a bad idea 
              to catch exceptions and place them into logfiles (except in the very high level of your application)!
          )
        {
            Now Check, that the Java-VM ClassLoader (Not your code!!!) will throw an ClassNotFoundException. 
            Why you not trusting the jvm developers? ;)
        }
    }