Mockito doNothing失效:void方法methodB仍执行的问题求助
问题分析与解决方案
为什么doNothing()不生效?
你测试类中mock的Product对象,和Service.methodA里new出来的Product实例完全是两个独立对象。Mockito的mock只能作用于被注入、传递的对象,无法直接替换代码中通过new关键字创建的实例,所以你对mock对象设置的doNothing()根本没作用到实际执行的那个Product上。
解决方案
方案一:重构Service,依赖注入Product(推荐)
把Product的创建逻辑从methodA中抽离,通过构造注入或Setter注入的方式传入Service,这样测试时就能轻松替换为mock对象。
修改后的Service类:
public class Service{ private final Product product; // 构造注入,也可使用Setter注入 public Service(Product product) { this.product = product; } public Response methodA(Request request) { product.init(); // 现在调用的是注入的product对象,测试时可替换为mock product.methodB(true); Response response = product.getResponse(); return response; } }
对应的测试类:
import org.powermock.modules.junit4.PowerMockRunner; import static org.mockito.Mockito.*; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(PowerMockRunner.class) public class ServiceTest { @Before public void setUp() throws IOException { MockitoAnnotations.initMocks(this); } @Mock private Product product; @Test public void testServiceProduct() throws Exception { // 将mock的product注入Service Service service = new Service(product); Request request = new Request(); // 模拟getResponse返回预期结果 Response mockResponse = new Response(); mockResponse.setMessage("202"); when(product.getResponse()).thenReturn(mockResponse); // 设置methodB执行空操作 doNothing().when(product).methodB(anyBoolean()); Response response = service.methodA(request); Assert.assertTrue(response.getMessage().equals("202")); // 可选:验证methodB确实被调用 verify(product).methodB(true); } }
方案二:用PowerMock拦截构造函数(不推荐,优先重构)
如果暂时无法重构Service,可以用PowerMock拦截Product的构造函数,让new Product()返回你预先mock的对象。
修改后的测试类:
import org.powermock.api.mockito.PowerMockito; import org.powermock.modules.junit4.PowerMockRunner; import static org.mockito.Mockito.*; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(PowerMockRunner.class) // 告知PowerMock需要处理的类 @PrepareForTest({Service.class, Product.class}) public class ServiceTest { @Before public void setUp() throws IOException { MockitoAnnotations.initMocks(this); } @Mock private Product product; @Test public void testServiceProduct() throws Exception { // 拦截Product的无参构造,返回mock对象 PowerMockito.whenNew(Product.class).withNoArguments().thenReturn(product); Service service = new Service(); Request request = new Request(); // 模拟init方法(如果业务需要) doNothing().when(product).init(); // 设置methodB执行空操作 doNothing().when(product).methodB(anyBoolean()); // 模拟getResponse返回预期结果 Response mockResponse = new Response(); mockResponse.setMessage("202"); when(product.getResponse()).thenReturn(mockResponse); Response response = service.methodA(request); Assert.assertTrue(response.getMessage().equals("202")); } }
内容的提问来源于stack exchange,提问作者Dookoto_Sea
相关产品推荐
相关产品推荐

