在某些情况下,会使用void 类型的方法来完成一些工作。因此,在单元测试中,也可能会面对它。 在之前的案例中,笔者介绍了两种Mock的场景:
1)在给定输入参数的情况下给出需要的输出结果(返回值)
2)在给定输入参数的情况下方法抛出某种类型的异常
对于被Mock的某个对象的void方法来说,对于之前的第一种场景是没有意义的。并且对于Mockito来说,如果在执行过程中遇到了void方法,则默认就是执行doNothing。不过它也有如下的两种测试场景:
1)验证程序的行为-该void方法是否被调用
2)在给定输入参数的情况下方法抛出某种类型的异常
譬如在之前的StockService中增加print方法,并申明为void类型。
public interface StockService {
public void print(Stock stock) throws BizException;
}
在Portfolio类的getMarketValue()方法的持仓组合价值的计算部分,来调用该方法
for(Stock stock:stocks){
stockService.print(stock);
marketValue += stockService.getPrice(stock) * stock.getQuantity();
}
可以看见,这种重构不会对现有的测试造成困扰
image.png
原先的用例还都是通过的。
接着,补充一个用例来验证这个方法被调用了几次
@Test
public void testPortfolioVerifyPrint(){
portfolio.setStocks(stocks);
when(stockService.getPrice(teslaStock)).thenReturn(500.00);
when(stockService.getPrice(amazonStock)).thenReturn(1000.00);
assertThat(portfolio.getMarketValue()).isEqualTo(105000.0);
verify(stockService,times(stocks.size())).print(any(Stock.class));
}
来看第二个关于异常的场景。这个和普通有返回值的方法的异常测试略有不同。
@Test
public void testPortfolioPrintException(){
String ep="Print Exception";
portfolio.setStocks(stocks);
doThrow(new BizException(ep)).when(stockService).print(teslaStock);
assertThatThrownBy(() -> portfolio.getMarketValue())
.isInstanceOf(BizException.class)
.hasMessageContaining(ep);
}
由于是void方法,类似这样的写法在语法上就不正确了。
when(stockService.print(teslaStock)).thenThrow(new BizException(ep));
因此,Mockito提供了doThrow的方式来解决,类似还要doReturn和thenReturn等,在后续的章节中笔者会通过案例来介绍差异。
通过这个测试用例,就展示了如何针对void方法抛出异常的情况进行测试了。









网友评论