Mockito异常模拟实战指南
在单元测试中,我们经常需要模拟方法调用时抛出异常的情况。Mockito作为Java领域里一个非常流行的模拟框架,提供了多种方式来模拟异常。本文将通过一个实际的代码示例,详细讲解如何使用Mockito来模拟异常,并展示如何测试这些异常。
模拟非检查型异常(Unchecked Exceptions)
在Java中,非检查型异常(RuntimeException及其子类)可以在不显式声明throws
子句的情况下抛出。Mockito提供了when-thenThrow
的方式来模拟这种情况。
示例代码
@Test
public void processTest() {
MyService myService = Mockito.mock(MyService.class);
Mockito.when(myService.doSomething()).thenThrow(new RuntimeException("Cannot process"));
MyProcessor myProcessor = new MyProcessor(myService);
try {
String returnedValue = myProcessor.process();
TestCase.fail();
} catch (Exception e) {
System.out.println("-- exception thrown --");
Assert.assertTrue(e instanceof RuntimeException);
Assert.assertEquals(e.getMessage(), "Cannot process");
}
}
模拟检查型异常(Checked Exceptions)
对于检查型异常,即那些需要在方法签名中声明的异常,Mockito同样提供了when-thenThrow
的方式来模拟。但是,如果尝试模拟一个方法抛出检查型异常,而该方法并没有声明抛出该异常,Mockito会抛出一个MockitoException
。
示例代码
@Test
public void processTest() throws Exception {
MyService myService = Mockito.mock(MyService.class);
Mockito.when(myService.doSomething2()).thenThrow(new Exception("Cannot process"));
MyProcessor myProcessor = new MyProcessor(myService);
try {
String returnedValue = myProcessor.process2();
TestCase.fail();
} catch (Throwable e) {
System.out.println("-- exception thrown --");
Assert.assertTrue(e instanceof Exception);
Assert.assertEquals(e.getMessage(), "Cannot process");
}
}
处理异常
在某些情况下,我们可能希望在测试中处理异常,而不是让测试失败。这时,可以在方法中添加异常处理逻辑。
示例代码
@Test
public void processTest() throws Exception {
MyService myService = Mockito.mock(MyService.class);
Mockito.when(myService.doSomething2()).thenThrow(new Exception("Cannot process"));
MyProcessor myProcessor = new MyProcessor(myService);
String returnedValue = myProcessor.process3();
Assert.assertEquals(returnedValue, "default-value");
}
使用doThrow-when
方法
当需要模拟一个void
方法抛出异常时,应该使用doThrow-when
方法。
示例代码
@Test
public void processTest() {
MyService myService = Mockito.mock(MyService.class);
Mockito.doThrow(new RuntimeException("Cannot process")).when(myService).doSomething();
MyProcessor myProcessor = new MyProcessor(myService);
try {
String returnedValue = myProcessor.process();
TestCase.fail();
} catch (Exception e) {
System.out.println("-- exception thrown --");
Assert.assertTrue(e instanceof RuntimeException);
Assert.assertEquals(e.getMessage(), "Cannot process");
}
}
项目依赖和技术栈
- mockito-core 3.3.3: Mockito的核心API和实现。
- junit 4.13: Java的单元测试框架。
- JDK 8: Java开发工具包。
- Maven 3.5.4: 项目管理和构建自动化工具。
通过本文的示例,你应该能够理解如何在单元测试中使用Mockito来模拟异常,并学会如何编写测试用例来验证异常处理逻辑。这将帮助你编写更加健壮和可靠的代码。