Home > Blockchain >  Method is returning null even after using when/thenReturn
Method is returning null even after using when/thenReturn

Time:09-27

As the title states,the response I am getting for the call I make, even using a mocked instance of the class I'm trying to test, I am not able to assert the response as not null. Even when I use a when/thenReturn, it somehow isn't working.

The Testcase I'm writing looks like this

@Mock Client clientMock;
@Mock DocumentType documentMock;
@Mock LambdaLogger logger;
@InjectMocks Handler handler;   // I have annotated the handler class with @ExtendWith(MockitoExtension.class and @RunWith(PowerMockRunner.class)

@Test
public void handleRequest() {
    Handler handler = new Handler();
    EventRequest request = buildEventRequest();
    String property1 = "abcd";
    String property2 = "1234";


    PowerMockito.whenNew(Client.class).withAnyArguments().thenReturn(clientMock);
    PowerMockito.when(clientMock.getToken(logger, "sampleId").thenReturn("sampleToken");
    PowerMockito.when(clientMock.getDocument(property1, property2, logger).thenReturn(document);
    Object result = handler.handleRequest(request, context);
    assertNotNull(result);
}

The method I'm trying to test:

public class Handler{

    public Object handleRequest(Object object, Context context) {
        DocumentType document = getTheDocument(object.getProperties());  //calls a private method within the same class
        if (document != null) {
            document.setNewProperties(abc);
        }
        return document;
    }

    private DocumentType getTheDocument(String property1, String property2, LambdaLogger.class) {
        Client client = new Client();  //trying to mock this client to get a document
        DocumentType document = new DocumentType();
        document = client.getDocument(property1, property2);  
        return document;
    }
}

The client class is something like this

public class Client{
    public Object getDocument(String property1, String property2, LambdaLogger logger) {
        String token = getToken(logger, property1);
        // Makes post call to get CloseableHttpResponse, uses this to call a static method to get the document
        Document document = AnotherClass.getDocument(closeableHttpResponse);
        // Creates an Unmarshaller from JAXBContext, for the DocumentType.class, get's data as inputstream
        document = (DocumentType) unmarshaller.unmarshall(inputstream);
        return document;
    }
   
    public String getToken(LambdaLogger logger, String id) {
        // returns AWSSecretsManager secret
    }
}

I wanted to know if I even require to mock the inner methods like getToken, and why the when(clientMock.getDocument(property1, property2, logger).thenReturn(document); doesn't work. I used PowerMockito's whenNew as a new object of type Client is created within the private method, but that doesn't seem to mock the client correctly.

Do I need to use ReflectionUtils to invoke the Private method within the Handler class and do something like this?

    Method getTheDocument = Handler.class.getDeclaredMethod("getTheDocument", String.class, String.class, LambdaLogger.class)
    getTheDocument.setAccessible(true);
    getTheDocument.invoke(handler, property1, property2, logger);  //want to stub a return value for getDocument but not sure how to, so left it as it is here

The unmarshaller.unmarshall(inputstream); is the point in the dataflow where the null is returned from, if that helps. I've tried a lot of stuff, and mocked inner methods to return mocked values, but nothing is working at this point. Please let me know if I'm missing something here, or if you have any suggestions. (P.S. I am not able to modify the original code, I can only add the test cases)

CodePudding user response:

First, @RunWith is a Junit4 annotation, not Junit5 contrary to @ExtendWith. So, your Powermock configuration won't work in JUnit5 context.

I wanted to know if I even require to mock the inner methods like getToken

Effectively, you don't need to mock getToken because you already mock the getDocument which calls getToken. getToken will never be reached.

You can look at this thread on how to mock new instance creation with Junit5 and Powermock: Mock whenever new instance created without PowerMockito JUnit5

  • Related