Mockito:无法在 Java 单元测试中抛出异常
Mockito: Cannot throw exception in Java Unit Test
我有以下服务和测试方法,我正在尝试代码执行 catch (ApplicationException e) { }
块。
public abstract class ApplicationException extends RuntimeException {
// ....
}
public void create(Request request) {
try {
// ...
} catch (ApplicationException e) {
// I want the code hits this block and check the values in here
}
}
测试方法如下:
@InjectMocks
private ProductServiceImpl productService;
@Test
public void test() {
// variable defnitions and stubbings (code omitted)
willAnswer( invocation -> { throw new RuntimeException("abc msg"); })
.given(productService).create(request);
// or
// doThrow(new RuntimeException()).when(productService).create(request);
// service method call
productService.create(Request request);
}
当我调试代码时,在 doThrow
行出现错误:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
那么,我该如何解决这个问题呢?
正如@Jesper 在评论中提到的,您没有正确使用 Mockito。
对于您的测试用例,您需要测试您的 ProductService.create
方法是否会处理给定场景中的错误。假设您的代码如下所示。
class ProductService {
private SomeOtherService someOtherService;
public void create(Request request) {
try {
someOtherService.execute();
} catch (ApplicationException e) {
// I want the code hits this block and check the values in here
enter code here
throw new MyException(e); // Here you can do something else
}
}
所以someOtherService.execute
可以抛出ApplicationException。我们需要测试我们的 ProductService.create
是否会捕获该异常并进行一些处理。在示例中,我们将抛出不同类型的异常。
@Mock
private SomeOtherService mockOtherService;
@InjectMocks
private ProductServiceImpl productService;
@Test
public void test() {
doThrow(new ApplicationException()).when(someOtherService).execute();
given(productService.create(request)).willThrow(new MyException());
}
与您的示例的主要区别在于,我们告诉 SomeOtherService 模拟在调用 execute 方法时它应该做什么。这是允许的,Mockito 知道如何使用模拟。
在您的示例中,您试图传递真实对象而不是模拟对象。 @InjectMock
注释是 shorthand 这个
this.productService = new ProductService(mockSomeOtherService);
所以它创建了一个新对象,其依赖被模拟。您可以在此处找到更多相关信息 .
我没有 运行 这个代码或测试它所以不要 C/P 它。
希望它能帮助您了解您的方法有什么问题。
我有以下服务和测试方法,我正在尝试代码执行 catch (ApplicationException e) { }
块。
public abstract class ApplicationException extends RuntimeException {
// ....
}
public void create(Request request) {
try {
// ...
} catch (ApplicationException e) {
// I want the code hits this block and check the values in here
}
}
测试方法如下:
@InjectMocks
private ProductServiceImpl productService;
@Test
public void test() {
// variable defnitions and stubbings (code omitted)
willAnswer( invocation -> { throw new RuntimeException("abc msg"); })
.given(productService).create(request);
// or
// doThrow(new RuntimeException()).when(productService).create(request);
// service method call
productService.create(Request request);
}
当我调试代码时,在 doThrow
行出现错误:
org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock!
那么,我该如何解决这个问题呢?
正如@Jesper 在评论中提到的,您没有正确使用 Mockito。
对于您的测试用例,您需要测试您的 ProductService.create
方法是否会处理给定场景中的错误。假设您的代码如下所示。
class ProductService {
private SomeOtherService someOtherService;
public void create(Request request) {
try {
someOtherService.execute();
} catch (ApplicationException e) {
// I want the code hits this block and check the values in here
enter code here
throw new MyException(e); // Here you can do something else
}
}
所以someOtherService.execute
可以抛出ApplicationException。我们需要测试我们的 ProductService.create
是否会捕获该异常并进行一些处理。在示例中,我们将抛出不同类型的异常。
@Mock
private SomeOtherService mockOtherService;
@InjectMocks
private ProductServiceImpl productService;
@Test
public void test() {
doThrow(new ApplicationException()).when(someOtherService).execute();
given(productService.create(request)).willThrow(new MyException());
}
与您的示例的主要区别在于,我们告诉 SomeOtherService 模拟在调用 execute 方法时它应该做什么。这是允许的,Mockito 知道如何使用模拟。
在您的示例中,您试图传递真实对象而不是模拟对象。 @InjectMock
注释是 shorthand 这个
this.productService = new ProductService(mockSomeOtherService);
所以它创建了一个新对象,其依赖被模拟。您可以在此处找到更多相关信息 .
我没有 运行 这个代码或测试它所以不要 C/P 它。
希望它能帮助您了解您的方法有什么问题。