0
votes

I'm trying to create some unit tests in Mockito, and mocking a WebServiceTemplate call that returns a JAXBElement. I continually run into a NullPointerException, along with internal Mockito errors. How do I successfully mock the method call in Mockito?

I've researched a few other problems in StackOverflow, and while some of the problems are similar, none of them have provided a successful mock and test. My tests continues to fail.

Here is the method call in my actual code, within the 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);
}

Here is how I'm trying to mock the call.

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

Where I have my "when" and "doReturn" statement, I have a NullPointer as well as internal errors from Mockito. I expect the mocked class to be able to be returned.

Here is the stack trace of the error when I run 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.
1
Please include the full stack trace.Turing85
I included the stack trace. Additionally, none of the actual arguments are primitive, and when I try to change it to any(), the method becomes ambiguous because there are multiple marshalSendAndReceive methods with various arguments.Andy Wong
Looks like your mocks are not initialized. Have you added @RunWith(MockitoJRunner.class) as class annotation? Does the problem persist if you initialize the mock explicitly(@Mock private WebServiceOperations template = mock(WebServiceOperations.class);)?Turing85
Another thing comping to mind is to replace any(JAXBElement.class) with any(Object.class) (this should take care of the ambiguity)Turing85
Hey this has solved my current issue, and I'm just trying to mock the uri within the call. I have an idea of how to do that, thanks for your help! Can't believe I missed the RunWith annotation.Andy Wong

1 Answers

1
votes

The error message indicates that your mocks are not initialized.

You have to tell JUnit to run with the Mockito runner:

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

This will, among other things, initialize your mocks.