在 Mockito 中模拟 "marshalSendandReceive" 方法调用时遇到问题

Having Issues Mocking "marshalSendandReceive" method call in Mockito

我正在尝试在 Mockito 中创建一些单元测试,并模拟 returns JAXBElement 的 WebServiceTemplate 调用。我不断 运行 进入 NullPointerException,以及内部 Mockito 错误。如何在 Mockito 中成功模拟方法调用?

我研究了 Whosebug 中的其他一些问题,虽然有些问题很相似,但其中 none 提供了成功的模拟和测试。我的测试继续失败。

这是我实际代码中的方法调用,在 SearchInvoker.class.

JAXBElement<SearchResponse> response = null;
JAXBElement<SearchRequest> req = soapClient.genConn(searchReq);

try {
    response = (JAXBElement<SearchResponse>) getWebServiceTemplate().marshalSendAndReceive(req, new SoapActionCallback("search"));
} catch (RuntimeException e) {
    throw new Exception(e);
}

下面是我尝试模拟调用的方式。

public class SearchInvokerTest extends PackageTest{

    @InjectMocks private SearchInvoker invoker;

    @Mock private SearchSoapClient soapClient;
    @Mock private WebServiceOperations template;

    @Test
    public void searchInvokerTest() throws Exception {
        ObjectFactory factory = new ObjectFactory();

        doReturn(factory.createSearchResponse(generateAwsSearchRsp())).when(template.marshalSendAndReceive(any(JAXBElement.class), any(WebServiceMessageCallback.class)));

        SearchResponse rsp = invoker.doSearch(new SearchRequestDVO());

        assertNotNull(rsp);
        assertEquals("123", rsp.getTraceID());
    }
}

在我有 "when" 和 "doReturn" 语句的地方,我有一个 NullPointer 以及来自 Mockito 的内部错误。我希望能够返回模拟的 class。

这是我 运行 mvn test:

时错误的堆栈跟踪
[ERROR] Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.018 s <<< FAILURE! - in SearchInvokerTest
[ERROR] searchInvokerTest(SearchInvokerTest)  Time elapsed: 0.002 s  <<< ERROR!
java.lang.NullPointerException
        at SearchInvokerTest.searchInvokerTest(SearchInvokerTest.java:33)

[ERROR] searchInvokerTest(SearchInvokerTest)  Time elapsed: 0.017 s  <<< ERROR!
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:

Misplaced or misused argument matcher detected here:

-> at SearchInvokerTest.searchInvokerTest(SymcorSearchInvokerTest.java:33)
-> at SearchInvokerTest.searchInvokerTest(SymcorSearchInvokerTest.java:33)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
    when(mock.get(anyInt())).thenReturn(null);
    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
    verify(mock).someMethod(contains("foo"))

This message may appear after an NullPointerException if the last matcher is returning an object
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
    when(mock.get(any())); // bad use, will raise NPE
    when(mock.get(anyInt())); // correct usage use

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.

错误消息表明您的模拟未初始化。

您必须使用 Mockito 运行ner 告诉 JUnit 运行:

[...]
@RunWith(MockitoJRunner.class)
public class SearchInvokerTest extends PackageTest {
    [...]
}

这将初始化您的模拟。