如何测试不返回任何内容的方法?

时间:2021-02-17 11:57:09

标签: java junit

我想测试以下代码。但由于它总是返回消息迁移完成,因此,我如何确定是否抛出异常以及它是否通过了 catch 块。

简单来说,我没有什么可断言的。

注意:我不允许在我的返回消息中附加额外的消息,它应该总是迁移完成

if (sourceCampaign.getId() > 0 || collect.size() > 0) {
    throw new IllegalStateException("ids are positive"); 

} catch(IllegalStateException e) {        
    logger.error("error", "Migration error, IDs are positive");                             
}

return("migration completed");

请耐心等待,因为我是编程领域的新手。

2 个答案:

答案 0 :(得分:1)

首先,这个方法应该改进。不要对控制流使用异常。由于在特定条件下抛出并捕获异常,因此只需使用该条件:

if (sourceCampaign.getId() > 0 || collect.size() > 0) {
    logger.error("error", "Migration error, IDs are positive");
}
return("migration completed");

现在,对于测试,您需要了解两件事:

  1. 该方法返回预期结果(这是一个简单的测试,因为该方法总是返回完全相同的内容)。
  2. 该方法调用了预期的功能。

第二个就在这里:

logger.error("error", "Migration error, IDs are positive");

您需要测试,当提供满足预期条件的 souceCampaign 和/或 collect 值时,error() 方法在 logger 上被调用.您可以通过为对象提供一个用于 loggermock 实例来实现这一点。

Java 有各种可用的模拟库(我过去使用过 Mockito,它很好地完成了这项工作)。根据您的架构,您可能还想开始学习依赖注入。 (或者至少是依赖倒置原则,如果不是任何特定的依赖注入框架。)但是通过模拟 logger,您可以断言在该模拟上调用了特定操作。

答案 1 :(得分:0)

代码的编写方式不容易测试。 您已经收到的替代答案是将其重写为更可测试的内容:

try {
   validate( sourceCampaign, collect);
} catch(IllegalStateException e) {
   manage(e);
}
finally {
   return("migration completed");
}

public void validate(...) throws IllegalStateException {
   if (sourceCampaign.getId() > 0 || collect.size() > 0) {
     throw new IllegalStateException("ids are positive"); 
   }
}

public void manage(Exception e) {
   logger.error("error", "Migration error, IDs are positive");
}

既然它们在不同的方法中分离,您可以测试每个部分是否按预期方式工作,也可以通过扩展原始类来模拟它们。

在 JUnit 4 中测试 validate 方法抛出异常的一种方法是使用规则 ExpectedException

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void testIllegalStateException() throws Exception {
        thrown.expect( IllegalStateException.class );
  
        ...
        new ClassName().validate( sourceCampaign, collect );
    }

据我所知,没有简单的方法来测试打印日志消息的单元测试。

请注意,我认为在这种情况下您不需要抛出异常,如果不满足条件,您可以记录错误。但其他人已经提供了这个答案。