javaunit-testingjunitmockingpowermockito

How to mock a newly created object for AWSLambda/AWSStepFunctions that uses ClientBuilders?


I have a class that I'm trying to test where it creates a new object of type AWSStepFunctions, and I'm trying to mock it to return a mock of the same type. I cannot change this original line of code, I can only add tests, so I was wondering how I could go about mocking it.

The class looks looks this --

Class class{
    public Object handleRequest(Object object, Context context) {
        AWSStepFunctions client = AWSStepFunctionsClientBuilder.standard().withClientConfiguration(new ClientConfiguration()).build();
        client.startExecution(...);
    }
}

The testing code looks like this -

public class ClassTest {
    @Test
    public void testHandlerRequest() {
        mockStatic(AWSStepFunctionsClientBuilder.class);  //mockStatic() and when() from PowerMockito
        AWSStepFunctions awsStepFunctionsMock = mock(AWSStepFunctions.class);
        AWSStepFunctionsClientBuilder awsStepFunctionsClientBuilder = mock(AWSStepFunctionsClientBuilder.class);
        ClientConfiguration configuration = mock(ClientConfiguration.class);

        PowerMockito.whenNew(ClientConfiguration.class).withAnyArguments().thenReturn(awsStepFunctionsMock);

        when(awsStepFunctionsClientBuilder.standard()).thenReturn(awsStepFunctionsClientBuilder);        
        when(awsStepFunctionsClientBuilder.withClientConfiguration()).thenReturn(awsStepFunctionsClientBuilder);
        when(awsStepFunctionsClientBuilder.build()).thenReturn(awsStepFunctionsMock);
        ... more when-thenreturns
    }
}

I'm running into errors such as NoSuchMethodError for the clientBuilder's mock.

I tried to use PowerMockito's whenNew to mock the creation of the new object of type AWSStepFunctions - PowerMockito.whenNew(AWSStepFunctions.class).withAnyArguments().thenReturn(awsStepFunctionsMock), but that doesn't seem to work as well. Is there a way to return this mock correctly?


Solution

  • You can directly mock static methods with Mockito and Junit5 without using Powermock.

    ClassTest

        @Test
        void test() throws IOException {
            try (MockedStatic<AWSStepFunctionsClientBuilder> awsMock = Mockito.mockStatic(AWSStepFunctionsClientBuilder.class, Mockito.RETURNS_DEEP_STUBS)) {
                AWSStepFunctions awsStepFunctionsMock = mock(AWSStepFunctions.class);
                // You can mock methods chaining when you specify Mockito.RETURNS_DEEP_STUBS
                awsMock.when(() -> AWSStepFunctionsClientBuilder.standard().withClientConfiguration(Mockito.any()).build()).thenReturn(awsStepFunctionsMock);
                
            }
        }
    

    You can read this post for more explanation about MockedStatic: https://www.baeldung.com/mockito-mock-static-methods
    And this one about Mockito.RETURNS_DEEP_STUBS: https://www.baeldung.com/mockito-fluent-apis

    Don't forget to configure Mockito to handle static mock :
    test/resources/mockito-extensions/org.mockito.plugins.MockMaker

    mock-maker-inline