You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:55:37