Quarkus中Mock类内部方法失效,测试未抛出预期异常求助
Quarkus Mock类内部方法失效问题解决
问题场景
现有Service类包含sendRequest方法,内部调用get方法并捕获异常后抛出自定义MyException:
@Getter @ApplicationScoped public class Service{ public byte[] sendRequest(Integer id, String name){ try { return get(id, name); } catch (Exception exception) { // 注:原代码拼写错误`Exteption`需修正为`Exception` throw new MyException("Error during get data " + exception.getMessage()); // 注:原代码`getMEssage`需修正为`getMessage` } } public byte[] get(Integer id, String name){ ...some code... } }
测试类尝试Mockget方法抛出异常,验证sendRequest的异常捕获逻辑,但测试失败:
@QuarkusTest // 注:原代码`QuakrusTest`需修正为`QuarkusTest` public class ServiceTest{ @InjectMock Service service; @Test void test(){ when(service.get(anyInt(), anyString())).thenThrow(new RuntimeException("MyError")); MyException myException = assertThrows(MyException.class, () -> service.sendRequest(1, "name")); assertEquals("Error during get data MyError", myException.getMessage()); } }
测试报错:
Expected MyException to be thrown but nothing was thrown.
原因分析
使用@InjectMock注入的是完全Mock的对象,默认所有方法都会被Mock而非执行真实逻辑。当调用service.sendRequest()时,Mock对象不会执行该方法的真实try/catch代码,自然不会触发异常捕获和MyException的抛出。
解决方案
改用@InjectSpy注入Spy对象——Spy会优先执行真实方法逻辑,仅对显式Stub的方法进行Mock:
修改后的测试类代码:
@QuarkusTest public class ServiceTest{ @InjectSpy Service service; @Test void test(){ // 使用doThrow...when语法避免触发真实get方法执行 doThrow(new RuntimeException("MyError")) .when(service) .get(anyInt(), anyString()); MyException myException = assertThrows(MyException.class, () -> service.sendRequest(1, "name")); assertEquals("Error during get data MyError", myException.getMessage()); } }
额外注意事项
- 必须修正原代码中的拼写错误:
Exteption→Exception、getMEssage()→getMessage()、@QuakrusTest→@QuarkusTest,这些错误可能导致编译或运行异常。 - 使用
doThrow().when()而非when().thenThrow()的原因:后者会先调用一次真实的get方法再设置Stub,若get方法有副作用(如数据库操作)可能影响测试,前者则直接设置Stub不会触发真实方法。
内容的提问来源于stack exchange,提问作者Dany
相关产品推荐
相关产品推荐

