Below is my repo class
public class RepoService {
@Autowired
private WebClient webClient;
public DIResponse createIdentity(DICreateRequest diCreateRequest) {
CreateReq createReq = diCreateRequestMapper.setRequest(diCreateRequest);
DIResponse diResponse = null;
UriComponents uriBuilder = UriComponentsBuilder
.fromUriString(url)
.build(false);
DIResponse apiResponse = webClient
.post()
.uri(uriBuilder.toUriString())
.body(Mono.just(createReq), CreateReq.class)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> clientResponse.bodyToMono(DIBadRequest.class).flatMap(errorResponse -> {
LOGGER.error(CLIENT_ERROR, "POST", clientResponse.statusCode(), errorResponse);
return Mono.error(new DataAccessException(ERROR_STATUS +clientResponse.statusCode()+ ERROR_DESC+ errorResponse.getDetail()));
}))
.bodyToMono(DIResponse.class)
.block();
return apiResponse;
}
}
Below is my Mockito junit test case
@Mock
private WebClient webClient;
@Mock
WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock;
@Mock
WebClient.RequestBodyUriSpec requestBodyUriSpecMock;
@Mock
WebClient.RequestBodySpec requestBodySpecMock;
@Mock
WebClient.RequestHeadersSpec requestHeadersSpecMock;
@Mock
WebClient.ResponseSpec responseSpecMock;
@InjectMocks
private RepoService repositoryService;
@Test
void testCreateIdentity() throws IOException {
DICreateRequest mockDICreateRequest = getMockDICreatReq();
CreateReq createReq = createDI();
DIResponse mockDIResponse = getDI();
when(diCreateRequestMapper.setRequest(mockDICreateRequest)).thenReturn(createReq);
when(webClient.post()).thenReturn(requestBodyUriSpecMock);
when(requestBodyUriSpecMock.uri((URI) any())).thenReturn(requestBodySpecMock);
when(requestBodySpecMock.body(any())).thenReturn(requestHeadersSpecMock);
when(requestHeadersSpecMock.retrieve()).thenReturn(responseSpecMock);
when(responseSpecMock.onStatus(any(), any())).thenReturn(responseSpecMock);
Mockito.when(responseSpecMock.bodyToMono(DIResponse.class)).thenReturn(Mono.just(mockDIResponse));
DIResponse result = repositoryService.createIdentity(mockDICreateRequest);
Assert.assertEquals(mockDIResponse.getId(), result.getId());
}
How can I cover testcases inside the .onStatus()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> clientResponse.bodyToMono(DIBadRequest.class).flatMap(errorResponse -> {
LOGGER.error(CLIENT_ERROR, “POST”, clientResponse.statusCode(), errorResponse);
You need to use a Mockito Answer
to get access to the lambda and call it as the real implementation would. Here is a simplified example:
package com.example.so;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
public class TestEg {
@Mock
private Thing thing;
@InjectMocks
private ToTest toTest;
@Test
public void theTest() {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Runnable lambda = invocationOnMock.getArgument(0);
lambda.run();
return null;
}
}).when(thing).onStatus(any());
toTest.doIt();
verify(thing).doSomething();
}
}
interface Thing {
public void onStatus(Runnable lambda);
void doSomething();
}
class ToTest {
private final Thing thing;
public ToTest(Thing thing) {
this.thing = thing;
}
public void doIt() {
thing.onStatus(() -> {
thing.doSomething();
});
}
}