如何测试一个没有 return 任何东西的方法?
How to test a method which does not return anything?
我想测试以下代码。但是因为它总是 return 一条消息 migration completed 因此,我如何确定异常是否被抛出以及它是否通过了 catch 块。
简单来说,我没有什么可断言的。
注意:我不允许在我的 return 消息中附加额外的消息,它应该始终是 迁移完成
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");
我是编程界的新人,请耐心等待。
首先,这个方法应该改进一下。不要将异常用于控制流。由于异常是在特定条件下抛出并捕获的,因此只需使用该条件:
if (sourceCampaign.getId() > 0 || collect.size() > 0) {
logger.error("error", "Migration error, IDs are positive");
}
return("migration completed");
现在,关于测试,您需要涵盖两件事:
- 方法 returns 预期结果(这是一个简单的测试,因为此方法总是 returns 完全相同的结果)。
- 该方法调用了预期的功能。
第二个就在这里:
logger.error("error", "Migration error, IDs are positive");
您需要测试,当提供满足预期条件的 souceCampaign
and/or collect
值时,error()
方法在 logger
。您可以通过为对象提供 mock 实例来实现 logger
.
Java 有各种可用的模拟库(我过去使用过 Mockito,它做得很好)。根据您的架构,您可能还想开始学习依赖注入。 (或者至少是依赖倒置原则,如果不是任何特定的依赖注入框架的话。)但是使用模拟 logger
你可以断言特定的操作是在那个模拟上调用的。
代码的编写方式不容易测试。
对您已经收到的答案的替代答案是将其重写为更可测试的内容:
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");
}
现在它们在不同的方法中分离,您可以测试每个部分是否以预期的方式工作,您也可以通过扩展原始的 class.
来模拟它们
在 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 );
}
据我所知,没有简单的方法可以通过单元测试来测试日志消息是否已打印。
请注意,我认为您不需要在这种情况下抛出异常,如果不满足条件,您可以记录错误。但其他人已经提供了答案。
我想测试以下代码。但是因为它总是 return 一条消息 migration completed 因此,我如何确定异常是否被抛出以及它是否通过了 catch 块。
简单来说,我没有什么可断言的。
注意:我不允许在我的 return 消息中附加额外的消息,它应该始终是 迁移完成
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");
我是编程界的新人,请耐心等待。
首先,这个方法应该改进一下。不要将异常用于控制流。由于异常是在特定条件下抛出并捕获的,因此只需使用该条件:
if (sourceCampaign.getId() > 0 || collect.size() > 0) {
logger.error("error", "Migration error, IDs are positive");
}
return("migration completed");
现在,关于测试,您需要涵盖两件事:
- 方法 returns 预期结果(这是一个简单的测试,因为此方法总是 returns 完全相同的结果)。
- 该方法调用了预期的功能。
第二个就在这里:
logger.error("error", "Migration error, IDs are positive");
您需要测试,当提供满足预期条件的 souceCampaign
and/or collect
值时,error()
方法在 logger
。您可以通过为对象提供 mock 实例来实现 logger
.
Java 有各种可用的模拟库(我过去使用过 Mockito,它做得很好)。根据您的架构,您可能还想开始学习依赖注入。 (或者至少是依赖倒置原则,如果不是任何特定的依赖注入框架的话。)但是使用模拟 logger
你可以断言特定的操作是在那个模拟上调用的。
代码的编写方式不容易测试。 对您已经收到的答案的替代答案是将其重写为更可测试的内容:
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");
}
现在它们在不同的方法中分离,您可以测试每个部分是否以预期的方式工作,您也可以通过扩展原始的 class.
来模拟它们在 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 );
}
据我所知,没有简单的方法可以通过单元测试来测试日志消息是否已打印。
请注意,我认为您不需要在这种情况下抛出异常,如果不满足条件,您可以记录错误。但其他人已经提供了答案。