首页 > 解决方案 > 当我测试另一个类时,Mockito 无法模拟第三类的属性

问题描述

我在使用 Mockito 时遇到问题,因为当我测试另一个类时,我无法模拟第三类的属性。

我正在测试的课程:

@Component
public class MyTransformer {
    @Autowired
    private MyService myService;
    
    public Output myMethod(Context context, Input input, Something something) throws Exception {
        ServiceInput serviceInput = createServiceInput(something);
        myService.doSomething(context, input, serviceInput);
        return new Output(); 
    }
}

上一个类中使用的接口:

public interface MyService {
    public void doSomething(Context context, Input input, Something something) throws Exception;
}

服务的真正实现:

@Service
public class MyServiceImpl implements MyService {

    @CustomServiceAnnotation(serviceName = "MyServiceName", apiPaths = {
        ServiceApiPath.class
    })
    private GatewayProxyInvoker gatewayProxyInvoker; // this property is null

    @Override
    public void doSomething(Context context, Input input, Something something) throws Exception {
        Request request = MyServiceCommand.createRequest(context, input, something);
        Response response = Invoker.invoke(Response.class, gatewayProxyInvoker, context, request);
    }
}

由于 gatewayProxyInvoker 属性为空而引发 NullPointerException 的类:

public class Invoker {
    public static T invoke(final Class<T> responseType, final GatewayProxyInvoker gatewayProxyInvoker, final Context context, S request) throws Exception {
        return gatewayProxyInvoker.invoke(responseType, context, request);
    }
}

测试类:

@RunWith(MockitoJUnitRunner.class)
public class MyTransformerTest {
    @InjectMocks
    private MyTransformer transformer;

    @Mock
    private MyServiceImpl myService;
    
    @Mock
    private GatewayProxyInvoker gatewayProxyInvoker;
    
    @Test
    public void myMethodTest() throws Exception {
        Response myResponse = new Response();
        
        doCallRealMethod().when(myService).doSomething(any(Context.class), any(Input.class), any(Something.class));
        
        when(gatewayProxyInvoker.invoke(any(Class.class), any(Context.class), any(Request.class))).thenReturn(myResponse);
        
        transformer.myMethod(/*valid input params*/);
    }
}

属性“gatewayProxyInvoker”为空,所以我想我在模拟它的过程中做错了什么。

代码工作正常,这是我的 JUnit 测试不工作。

当我测试另一个属性时,如何模拟第三类的属性?在我的示例中,您可以看到该方法是无效的,我正在测试的类使用接口。

谢谢大家,伙计们!

标签: javaspring-bootmockitojunit4

解决方案


我在这里找到了一个解决方案:Mockito Inject mock into Spy object

这个例子效果很好:

@RunWith(MockitoJUnitRunner.class)
public class MyTransformerTest {
    @InjectMocks
    private MyTransformer transformer;

    @InjectMocks
    private MyServiceImpl myService;
    
    @Mock
    private GatewayProxyInvoker gatewayProxyInvoker;
    
    @Before
    public void init() {
        myService = Mockito.spy(new MyServiceImpl());
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void myMethodTest() throws Exception {
        Response myResponse = new Response();
        when(gatewayProxyInvoker.invoke(any(Class.class), any(Context.class), any(Request.class))).thenReturn(myResponse);
        transformer.myMethod(/*valid input params*/);
    }
}

推荐阅读