-1

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();
}
}
4

3 に答える 3

2

@Test アノテーションを使用するだけです

@Test(expected=RuntimeException.class)

もう1つの解決策は、例外が予想される場合は、テストを失敗させることです

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

更新 #1:

あなたのコードでは、すべての「良い」例外をキャッチしているため、コードとテストケースはあまり良くないと思います! しかし、彼らは何がうまくいかなかったかをあなたに伝えています。

したがって、コードでこれらの例外をスローさせてください。

しかし、反対側は次のとおりです。標準のjavaまたはjava.sql機能 (ClassLoading、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? ;)
    }
}
于 2013-10-21T10:26:14.293 に答える
0

メソッドconnectionInit ()は、現在書かれているように、例外をスローしません。両方のテスト ケースで、(コードで理解できることから) 予想される失敗をチェックしていると思われますがfail ()、失敗が発生しない場合は JUnit メソッドを呼び出さないため、両方のテスト ケースが合格しているという印象を受けます。どちらも失敗するはずです。Mirko が述べたように、コードを への呼び出しfail ()の後に呼び出すように変更する必要がありますconnectionInit ()

于 2013-10-21T12:22:47.740 に答える