javamockingmockitokeycloakstubbing

Stubbing Keycloak SimpleHttp.Response.asJson​(Class<T> type)


I am having trouble stubbing the SimpleHttp.Response.asJson(Class<T> type) method. Here is the doc: keycloak simplehttp

Here is the sample code that I would like to stub:

SampleResponse sampleResp = response.asJson(SampleResponse.class);

Here is the method I am trying to test:

    public SampleResponse getCustomer(String clientID) throws ResponseFailureException {

        String url = String.format("%s/customer", this.baseUrl);
        Instant start = Instant.now();
        try {
            // Build request
            // 
            SimpleHttp req = SimpleHttp
                .doGet(url, httpClient)
                .param("client_id", clientID)
                .json(null);

            // Fire the request
            // 
            SimpleHttp.Response response = req.asResponse();
            if (response.getStatus() != HttpStatus.SC_OK) {
                throw new ResponseFailureException("Fail");
            }

            // Parse response
            // Target code to stub
            SampleResponse sampleResp = response.asJson(SampleResponse.class);

            return sampleResp;
        } catch (Exception e) {
            throw new ResponseFailureException("Fail", e);
        }
    }

Here is the test:

class ClientTest {

    @Mock
    private KeycloakSession keycloakSession;
    
    @Mock
    private HttpClientProvider httpClientProvider;
    
    @Mock
    private CloseableHttpClient httpClient;
    
    @Mock
    private SimpleHttp simpleHttp;
    
    @Mock
    private SimpleHttp.Response response;
    
    private Client testClient;

    @BeforeEach
    void setUp() {
        when(keycloakSession.getProvider(HttpClientProvider.class)).thenReturn(httpClientProvider);
        when(httpClientProvider.getHttpClient()).thenReturn(httpClient);
        testClient = new Client(keycloakSession, "https://api.example.com", "BASIC", "user", "pass");
    }

    @Test
    void getCustomer_shouldReturnResponse_whenValidInputsProvided() throws Exception {
        // Mock `SimpleHttp.doGet()` correctly with KeycloakSession

        try (MockedStatic<SimpleHttp> mockedSimpleHttp = mockStatic(SimpleHttp.class)) {
            mockedSimpleHttp.when(() -> SimpleHttp.doGet(eq("https://api.example.com/customer"), eq(httpClient)))
                    .thenReturn(simpleHttp);

            // Mock behavior of the SimpleHttp instance
            when(simpleHttp.header(anyString(), anyString())).thenReturn(simpleHttp);
            when(simpleHttp.param(anyString(), anyString())).thenReturn(simpleHttp);
            when(simpleHttp.json(null)).thenReturn(simpleHttp);
            when(simpleHttp.asResponse()).thenReturn(response);

            String jsonResponse = "{\"customerInfo\": {\"name\": \"testName\", \"permissions\": \"admin\"}}";

            ObjectMapper mapper = new ObjectMapper();
            JsonNode node = mapper.readTree(jsonResponse);

            // Mock the response
            when(response.getStatus()).thenReturn(200);
            when(response.asJson()).thenReturn(node);
            SampleResponse sampleResponse = new SampleResponse();

            // Stub the asJson method
            // Errors in this line of code
            when(response.asJson(any(SampleResponse.class))).thenReturn(sampleResponse);

            // Call the actual method
            SampleResponse result = testClient.getCustomer("client123");

            // Verify the expected result
            assertNotNull(result);
        }
    }
}

I have tried asking ChatGPT for solutions however the solution provided still fails. Here is a sample solution:

SampleResponse sampleResponse = new SampleResponse();
when(response.asJson(SampleResponse.class)).thenReturn(sampleResponse);

It returns this error:

org.mockito.exceptions.misusing.NotAMockException: Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class java.lang.Class!

I have also tried this solution:

when(response.asJson(any(SampleResponse.class))).thenReturn(sampleResponse);

It still fails and returns this error:

no suitable method found for asJson(sampleResponse)
    method org.keycloak.broker.provider.util.SimpleHttp.Response.<T>asJson(java.lang.Class<T>) is not applicable
      (inference variable T has incompatible bounds
        equality constraints: sampleResponse
        lower bounds: java.lang.Object,java.lang.Class<T>)
    method org.keycloak.broker.provider.util.SimpleHttp.Response.<T>asJson(com.fasterxml.jackson.core.type.TypeReference<T>) is not applicable
      (inference variable T has incompatible bounds
        equality constraints: sampleResponse
        lower bounds: java.lang.Object,com.fasterxml.jackson.core.type.TypeReference<T>

Solution

  • Used:

    SampleResponse sampleResponse = mock(SampleResponse.class);
    when(response.asJson(SampleResponse.class)).thenReturn(sampleResponse);
    

    to make it work.