如何在Mockito中Mock new()调用?无法修改源码场景求助
如何Mock通过new()创建的StockValidator对象(无需修改源码)
你遇到的问题是Mockito核心库无法直接mock方法内通过new()创建的对象,因为这类对象和你通过@MockBean声明的实例完全无关。要解决这个问题,需要用到PowerMock——它是Mockito的扩展库,支持拦截new操作并返回mock实例。
步骤1:添加PowerMock依赖
如果用Maven,在pom.xml中添加以下依赖(注意和你当前Mockito版本兼容,示例为Mockito 3.x/4.x对应的PowerMock版本):
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency>
步骤2:配置测试类注解
在你的测试类上添加PowerMock的运行器和需要预处理的类(必须包含调用new StockValidator()的那个类,也就是StockService):
@RunWith(PowerMockRunner.class) @PrepareForTest(StockService.class) // 关键:指定包含new操作的类 public class StockServiceTest { @Mock private StockValidator stockValidator; @InjectMocks private StockService stockService; // 用@InjectMocks代替@Autowired,避免Spring上下文冲突(纯单元测试场景) @Test public void testBuyStock() { StockRequest stockRequest = new StockRequest(); // 拦截new StockValidator()操作,返回我们的mock实例 PowerMockito.whenNew(StockValidator.class) .withAnyArguments() // 匹配任意构造参数 .thenReturn(stockValidator); // 设置mock方法的返回值 Mockito.when(stockValidator.validateRequest(stockRequest)) .thenReturn(null); // 执行测试方法 StockResponse response = stockService.buyStock(stockRequest); // 验证mock方法被调用 Mockito.verify(stockValidator).validateRequest(stockRequest); // 其他业务逻辑断言... } }
关键说明
@PrepareForTest(StockService.class):PowerMock需要修改这个类的字节码,才能拦截其中的new操作,这一步绝对不能少。PowerMockito.whenNew():专门用来拦截指定类的new实例化操作,你可以通过withArguments(...)匹配特定构造参数,也可以用withAnyArguments()匹配任意参数。- 如果是Spring Boot集成测试(需要
@SpringBootTest),PowerMock和Spring Test的兼容需要额外配置,建议优先用纯单元测试(@InjectMocks注入依赖)来避免复杂配置。
替代方案(限可修改源码场景)
如果后续允许修改源码,更优雅的方式是把StockValidator的创建逻辑抽成工厂方法或依赖注入,但你明确说不能改源码,所以这个方案暂不适用。
内容的提问来源于stack exchange,提问作者Shivayan Mukherjee
相关产品推荐
相关产品推荐

