JAVA:传递给 when() 的 JUNIT 参数不是模拟

JAVA : JUNIT Argument passed to when() is not a mock

我正在尝试 运行 对以下功能进行单元测试


    @Autowired
    private EmailServiceConfigProperties emailServiceConfigProperties;
    
    @Autowired
    private HttpHandler httpHandler;
        
    public TransactionalEmailResponse sendPostRequestForTransactionalEmail(String endpoint, TransactionalEmail emailRequestBody) {
        HttpHeaders httpHeaders = setHttpHeaders(); 
        ResponseEntity<TransactionalEmailResponse> response = null;
        try {
            response = httpHandler.sendPost(endpoint, httpHeaders, emailRequestBody, TransactionalEmailResponse.class);
        } catch (Exception e) {
            logger.error("An error while sending POST request to email-service : " + JsonUtils.jsonize(emailRequestBody), e);
        }
        TransactionalEmailResponse body = response.getBody();
        return body;
    }

下面是同样的单元测试:

@InjectMocks
    private APIKeyAuthHandler testAPIKeyAuthHandler;
    
    @Mock
    private HttpHandler httpHandler;
    
    @Mock
    private EmailServiceConfigProperties emailServiceConfigPropertiesMock;

@Test
    public void testSendPostRequestForTransactionalEmail() {
        TransactionalEmail transactionalEmail = getTransactionalEmailRequestBody(); //returns POJO
        TransactionalEmailResponse transactionalEmailResponse = transcationEmailResponse();
        
        Mockito.doReturn(setHttpHeaders()).when(testAPIKeyAuthHandler).setHttpHeaders(); returns POJO
        String sendEmailEndpoint = "https://dev.com/api/v2/send/email";
        Mockito.when(httpHandler.sendPost(sendEmailEndpoint, setHttpHeaders(), transactionalEmail, TransactionalEmailResponse.class))
        .thenReturn(new ResponseEntity<>(transactionalEmailResponse, HttpStatus.OK));
        
        assertNotNull(testAPIKeyAuthHandler.sendPostRequestForTransactionalEmail(sendEmailEndpoint, transactionalEmail));
    }

错误日志如下:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to when() is not a mock!
Example of correct stubbing:
    doThrow(new RuntimeException()).when(mock).someMethod();
    at service.api.handlers.APIKeyAuthHandlerUnitTest.testSendPostRequestForTransactionalEmail(APIKeyAuthHandlerUnitTest.java:42)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod[=13=](ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke[=13=](ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)

有人可以帮我解决这个问题吗? 谢谢

这里:

when(testAPIKeyAuthHandler)

但是:

@InjectMocks
private APIKeyAuthHandler testAPIKeyAuthHandler;

testAPIKeyAuthHandler 不是 模拟,when() 规范的语法不会改变这一点。

含义:@InjectMocks 注释创建模拟。它创建一个对象,Mockito 将尝试用您的模拟对象填充

但是请注意,真正的答案是:这些事情很复杂。您无法通过反复试验学习如何将 mockito 与 spring 等复杂框架结合使用。因此:你最好退后一步。选择一个关于如何使用 mockito 的好教程。阅读它,然后 了解 如何以正确的方式使用 Mockito。 然后 拿起一个教程,结合 spring 解释 Mockito,阅读它,理解它。 然后将您学到的知识应用到您的设置中。