当我测试另一个时,Mockito 无法模拟三分之一 class 的 属性

Mockito can't mock a property of a third class when I'm testing another one

我在使用 Mockito 时遇到了问题,因为我在测试另一个 class 时无法模拟 属性 的三分之一。

我正在测试的class:

@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(); 
    }
}

前面使用的接口class:

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);
    }
}

抛出 NullPointerException 的 class 因为 gatewayProxyInvoker 属性 为 null:

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);
    }
}

测试class:

@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 测试不工作。

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

谢谢大家!

我在这里找到了解决方案:

这个例子运行良好:

@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*/);
    }
}