【问题标题】:EasyMock Exception HandlingEasyMock 异常处理
【发布时间】:2013-03-01 16:29:45
【问题描述】:

我正在使用 EasyMock 创建一些 junit 测试用例。到目前为止,我期望返回 POJO 的类是有意义的,但我应该如何处理本身可能引发异常的 DAO 对象。我的测试用例是检查 DAO 遇到问题时抛出的预期异常。使用 EasyMock 我尝试模拟 DAO 对象(从 foo 类测试),处理较低级别 DAO 异常的正确方法是什么。

类/简单调用的示例如下:(假设所有 getter/setter/构造函数都有效且存在)

public class foo{
    private daoClass dao = daoClass.getInstance();
    public String getValueFromDB(String key) throws DBException{
        return dao.lookup(key);
    }
}

public class daoClass{ //singleton DAO 
    public daoClass getInstance(){
       //singleton access here
    }
    public String lookup(String key) throws DBException{
        try{
            //DB LOGIC
        }
        catch(Exception e){
            throw new DBException(e.getMessage());
        }
    }
}

当我尝试测试 foo 类时,我希望能够测试此 DBException。我该如何处理这个问题,我应该在 try/catch 中(在测试中)包围 DAO 调用,还是在测试中添加 throws?我知道expected=DBException 会通过测试,但如果发生这种情况,您应该如何处理任意数量的内部异常?

测试代码示例:

@Test(expected=DBException.class)
public void testFooError(){
    String key = "test";
    String value = "expected";
    daoClass daoMock = createMock(daoClass.class);
    try{
        expect(daoMock.lookup(key)).andReturn(value);
    } catch (DBException e){
        // ???
    }
}

当expect 可能引发错误时,正确的处理方法是什么?测试方法throw 应该例外,还是应该使用try/catch?在测试中使用expected=EXCEPTION标签仍然正确吗?

【问题讨论】:

    标签: java junit easymock


    【解决方案1】:

    这是我在单元测试中处理异常的方式:

    如果你没有显式测试异常,那么你应该在方法中添加一个 throws 子句 - 如果异常被抛出并且你不希望它被抛出,那么这就是一个测试失败。 例如,

    @Test
    public void testFooNormal() throws DBException{
        String key = "test";
        String value = "expected";
        daoClass daoMock = createMock(daoClass.class);
        expect(daoMock.lookup(key)).andReturn(value);
        // do an assert on returned value
        ...
    }
    

    如果您正在显式测试异常,则在您期望它被抛出的行周围放置一个 try-catch(捕获您期望的最窄版本的异常),然后设置一个布尔值在 catch 子句中,assert 应该是布尔值。 例如,

    @Test
    public void testFooError(){
        String key = "test";
        String value = "expected";
        boolean exceptionThrown = false;
        daoClass daoMock = createMock(daoClass.class);
        try{
          expect(daoMock.lookup(key)).andReturn(value);
        }catch (DBException e) {
          exceptionThrown = true;
        }
        // assert exceptionThrown is true
        ...
    }
    

    这是测试异常的好方法,因为这意味着您不仅要测试是否抛出了正确的异常,还要测试它是从您期望的行中抛出的。如果您使用 @test(expected=...) 则测试中的不同行可能会引发该异常,并且测试可能会错误地通过。

    【讨论】:

    • 所以底部的情况是我正在寻找的(期待例外),所以(expected=Exception.class) 在这种情况下应该被忽略?
    • 快速澄清exceptionThrown 逻辑...我是否希望在expect 调用 EasyMock 对象时出现此异常,或者我应该稍后在测试代码中使用该逻辑当我实际使用模拟对象并希望触发时。 try{ expect() } catch { DO NOTHING } ...try{foo.getValueFromDB(value)} catch (Exception e) { exceptionThrown = true;}
    【解决方案2】:

    您的 DAO 逻辑不应根据您的测试而改变。如果您希望您的 DAO 抛出异常,请保持这种状态并以您正在测试的方式测试异常。

    如果您在 DAO 本身中捕获异常以执行回滚或日志记录等,那么测试用例不应期待 Exception,因为它不是测试用例场景。在这种情况下,您可以检查 NULL ,因为我希望您的 DAO 将返回 NULL 。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多