【问题标题】:How do I write test code for testing my exception handling code?如何编写测试代码来测试我的异常处理代码?
【发布时间】:2016-10-08 05:54:44
【问题描述】:

我正在为遗留 Java 代码编写单元测试。现在我遇到了一个问题。下面是我要为其编写测试代码的class A。

class A {

    public A(){

    }

    public void doSomething()throws DBException {
        try{
            //some code that might throw JDBCConnectionException 
        }catch(JDBCConnectionException e){
            notifyJDBCConnection()
        }catch(Exception e){

        }
    }   

    private void notifyJDBCConnection(){
        //do notification stuff
    }
}

现在说,当JDBCConnectionException被捕获时,我是否需要测试方法notifyJDBCConnection()是否已经执行。解决这个问题的正确方法是什么?或者我应该只写一个测试方法notifyJDBCConnection可以吗?

【问题讨论】:

  • 为什么notifyJDBCConnection 是公开的?它是从另一个类调用的吗?
  • @saka1029 是的,我认为你是对的。它仅从class A 调用,不应为public。
  • 感谢您的惊喜接受 ;-)

标签: java unit-testing junit mockito junit4


【解决方案1】:

我认为notifyJDBCConnection 会调用某种通知框架,无论是电子邮件发件人还是其他。如果您使用 Mockito 之类的框架模拟该组件,您可以验证是否已对所述组件进行了适当的调用。

【讨论】:

  • 是的。那么这是否意味着我不必编写测试代码来涵盖从try 块到catch 块的逻辑,包括异常处理部分?我只需要使用 Mockito 来测试通知组件,对吧?
  • 好吧,你需要让它以某种方式调用通知方法。它是否调用了您也可以模拟的 JDBC 对象?
  • 你的意思是notifyJDBCConnection?不,它只负责向其他组件发送消息。
  • 我的意思是doSomething 会在某个时候进行 JDBC 调用。模拟它以抛出异常并检查您的模拟通知组件是否被调用。
【解决方案2】:

一种方法:

  1. 您将处理该异常的责任放到它自己的类中。
  2. 然后您使用依赖注入将新类的对象提供给您的类A。
  3. 现在您可以使用模拟框架(例如 EasyMock 或 Mokito)将该异常处理程序类的模拟实例传递给 A。
  4. 最后,您验证您的模拟对象是否可以看到预期的调用。

这种方法表面上看起来像是“更多的工作”,但它可以带来更好的设计 - 因为您将关注点分开;并且通过创建一个特殊的异常处理程序类,您也可以自己测试那个类!

【讨论】:

    【解决方案3】:

    使用 Mockito 和 JUnit 的解决方案,采用 GhostCat 建议的设计:

    class A {
        private final JDBCConnectionNotifier notifier;
    
        public A(JDBCConnectionNotifier notifier){
            this.notifier = notifier;
        }
    
        public void doSomething()throws DBException {
            try{
                //some code that might throw JDBCConnectionException 
            }catch(JDBCConnectionException e){
                notifier.notifyJDBCConnection()
            }catch(Exception e){
    
            }
        }   
    }
    

    所以测试类将是:

    import static org.mockito.Mockito.*;
    import org.junit.*;
    
    class ATest {
        @Test
        public void shouldCallNotifierOnJDBCConnectionException() throws Exception {
            JDBCConnectionNotifier notifier = mock(JDBCConnectionNotifier.class);
            A a = new A(notifier);
    
            a.doSomething();
    
            verify(notifier).notifyJDBCConnection();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-24
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多