I am calling external service using send() method of HttpClient's instance.
public class MyProgram {
private String producerEndpoint;
private HttpClient httpClient;
@Autowired
public EsignEventProducer(@Value("${producer.http.endpoint}")String producerEndpoint) {
this.producerEndpoint=producerEndpoint;
this.httpClient=HttpClient.newBuilder().build();
}
public void sendMessage(ObjectMapper objectMapper, String jsonString, String xCorrelationId) throws Exception {
ProduceRequest produceRequest=new ProduceRequest();
ProduceRecord produceRecord=new ProduceRecord();
produceRecord.setValue(Optional.of(objectMapper.readTree(jsonString)));
produceRequest.setRecords(Arrays.asList(produceRecord));
HttpRequest request=HttpRequest.newBuilder()
.uri(URI.create(producerEndpoint))
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(produceRequest)))
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
.setHeader(IdTypeConstants.XCORRELATIONID, xCorrelationId)
.build();
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}
}
While creating Junit Testcases, I am mocking httpClient.send(request, HttpResponse.BodyHandlers.ofString());
as given below, but still instead of mocking, it is calling actual method.
Following is Junit Test class.
class MyProgramTest {
@InjectMocks
private MyEventProducer myEventProducer;
private HttpClient httpClient;
private HttpResponse<Object> httpResponse;
@Mock
private HttpRequest request;
private MyEvent schema;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
schema = new MyEvent();
schema.setId("123");
schema.setName("PACKAGE_COMPLETE");
schema.setCreatedDate("2021-10-20T16:17:58.408Z");
schema.setSessionUser("dummySession");
httpClient = Mockito.mock(HttpClient.class);
httpResponse = Mockito.mock(HttpResponse.class);
}
@Test
void testSendMessage() throws Exception {
ReflectionTestUtils.setField(myEventProducer, "producerEndpoint", "http://localhost:8080/endpointservice/my_topic");
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(schema);
String xCorrelationId = "dummyXCorrelationId";
Mockito.when(httpClient.send(Mockito.any(HttpRequest.class), HttpResponse.BodyHandlers.ofString())).thenReturn(null);
myEventProducer.sendMessage(objectMapper, jsonString, xCorrelationId);
verify(httpClient).send(request, HttpResponse.BodyHandlers.ofString());
}
}
I am using Junit 5 with gradle and httpClient from java.net package. Please help, Thanks
CodePudding user response:
The problem is that the EsignEventProducer
constructor creates a new HttpClient
, rather than using the mock. Instead, the HttpClient
instance should be passed into the constructor.
@Autowired
public EsignEventProducer(@Value("${producer.http.endpoint}") String producerEndpoint, HttpClient httpClient) {
this.producerEndpoint = producerEndpoint;
this.httpClient = httpClient;
}
CodePudding user response:
There are a couple of thing mixed up in your test, I would stick to one type of mock creation, either via annotations or explicitly.
The main problem is, as Tim Moore mentioned, is that your mock is not injected.
You are calling MockitoAnnotations.initMocks(this);
before httpClient = Mockito.mock(HttpClient.class);
, so your HttpClient mock isn't injected. The easiest way would be to annotate the httpClient field like this:
@Mock
private HttpClient httpClient;
and delete the explicit Mockito.mock(HttpClient.class);
call in your setup method.
So the whole class would look like this:
class MyProgramTest {
@InjectMocks
private MyEventProducer myEventProducer;
@Mock
private HttpClient httpClient;
@Mock
private HttpResponse<Object> httpResponse;
@Mock
private HttpRequest request;
private MyEvent schema;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
schema = new MyEvent();
schema.setId("123");
schema.setName("PACKAGE_COMPLETE");
schema.setCreatedDate("2021-10-20T16:17:58.408Z");
schema.setSessionUser("dummySession");
}
@Test
void testSendMessage() throws Exception {
ReflectionTestUtils.setField(myEventProducer, "producerEndpoint", "http://localhost:8080/endpointservice/my_topic");
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(schema);
String xCorrelationId = "dummyXCorrelationId";
Mockito.when(httpClient.send(Mockito.any(HttpRequest.class), HttpResponse.BodyHandlers.ofString())).thenReturn(null);
myEventProducer.sendMessage(objectMapper, jsonString, xCorrelationId);
verify(httpClient).send(request, HttpResponse.BodyHandlers.ofString());
}
}