How to use mockito for elasticSearchClient while updating? - java

Note client is RestHightLevelClient,
#Override
public void createAlias(final String aliasName, final String indexName, final boolean writable)
throws IOException {
IndicesAliasesRequest request = new IndicesAliasesRequest();
AliasActions aliasAction = new AliasActions(AliasActions.Type.ADD).index(indexName)
.alias(aliasName);
if (writable) {
aliasAction.writeIndex(true);
}
request.addAliasAction(aliasAction);
AcknowledgedResponse response = client.indices().updateAliases(request, RequestOptions.DEFAULT);
}
I tried writing test case for this :
#Test
void testCreateAlias() throws IOException {
AcknowledgedResponse response = AcknowledgedResponse.of(true);
when(client.indices().updateAliases(Mockito.mock(IndicesAliasesRequest.class), RequestOptions.DEFAULT))
.thenReturn(response);
searchManagerService.createAlias("test", "test_idx", true);
}
ERROR : client.indices() is null,
How to resolve this ?

Mock client.indices() to return a mocked instance of IndicesClient. Then mock that IndicesClient updateAliases method to return response.
var mockedIndicesClient = Mockito.mock(IndicesClient.class);
when(client.indices()).thenReturn(mockedIndicesClient);
when(mockedIndicesClient.updateAliases(Mockito.mock(IndicesAliasesRequest.class), RequestOptions.DEFAULT)).thenReturn(response);
Also I believe you want to use matchers in the last line. any(IndicesAliasesRequest.class) instead of Mockito.mock:
when(mockedIndicesClient.updateAliases(any(IndicesAliasesRequest.class), RequestOptions.DEFAULT)).thenReturn(response);

Related

Junit doReturn does not return correct response type

I am writing Junit for a method which has two methods, which has two different Rest calls but each rest call returns different response object.
When I try to mock this behavior using doReturn(responsetype1).when(restcall1), first rest call gets success with return type as responsetype1 but for second method doReturn(responsetype2).when(restcall2) fails because doReturn(responsetype2) is not working instead it is still giving responsetype1. Someone please help with this
public mainResponse add(HttpServletRequest request, String string1, HttpHeaders headers,
List<String> list) {
boolean deleteStatus = method1(request, string1);
if (!deleteStatus) {
collectionResponse = method2(string1, colId, headers);
}
}
public boolean method1(HttpServletRequest request, String string1) throws Exception {
ResponseEntity<ResponseType1> responseType1 = restTemplate.exchange(url1, HttpMethod.GET, new HttpEntity<>(headers),
ResponseType1.class);
//perfrom certain operation and return response
return status;
}
ResponseType2 method2(String string1, String colId , HttpHeaders headers) {
ResponseEntity<ResponseType2> response = restTemplate.exchange(url2, HttpMethod.POST,
new HttpEntity<>(body, headers), ResponseType2.class);
return response.getBody(); //**this line is failing because ResponseType1 is being returned here**
}
My test class :
#Test
public void test() throws Exception {
doReturn(**ResponseType1**).when(restTemplate).exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(), ArgumentMatchers.<Class<ResponseType1>>any());
doReturn(**ResponseType2**).when(restTemplate).exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(), ArgumentMatchers.<Class<ResponseType2>>any());
//other operation
}

write unit test case for this method returning RxJava Future

Can any one please help me to write a unit test case for this method returning RxJava Future object , I am able to write and mock for a method returning Single.
public Future<JsonObject> fetchVendorDetailsVendorIdAsFuture(String serviceURI, Map<String, String> headerMap) {
if(vbConnectorCircuitBreaker == null){
vbConnectorCircuitBreaker= CircuitBreakers.getVbConnectorCircuitBreaker();
}
return vbConnectorCircuitBreaker.execute(future -> {
// get ok http client
OkHttpClient client = okHTTPClientHelper.getOkHTTPClient();
if(client != null){
try{
MediaType mediaType = MediaType.parse("application/json");
Headers headers = Headers.of(headerMap);
Request request = new Request.Builder()
.url(serviceURI)
.get()
.headers(headers)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, Response response)
throws IOException {
String jsonData = response.body().string();
JsonObject jsonObject = new JsonObject(jsonData);
future.complete(jsonObject);
}
public void onFailure(Call call, IOException e) {
future.complete(null);
}
});
} catch(Exception exception) {
future.complete(null);
}
} else {
future.complete(null);
}
});
}
You can try using okhttp's MockWebServer.
That way, your Call can emit a real http request and you will be able to handle the server's response.
You can create the mocked server's response yourself using mockWebServer.enqueue(new MockResponse() ... )
There are a lot of different ways to write tests for this kind of problem and here is my suggestion:
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
// other imports omitted
#ExtendWith(VertxExtension.class)
#Slf4j
public class VendorDetailsTest {
private VendorDetailsVerticle sut;
private MockWebServer mockWebServer;
#BeforeEach
public void setUp() {
sut = new VendorDetailsVerticle();
mockWebServer = new MockWebServer();
}
#Test
public void testExecuteService(final Vertx vertx, final VertxTestContext testContext)
throws InterruptedException {
// given -----
final JsonObject serverResponsePayload = new JsonObject().put("futureCompleted", true);
mockWebServer.enqueue(new MockResponse()
.setBody(serverResponsePayload.encode())
.setResponseCode(200)
.setHeader("content-type", "application/json"));
// when -----
final Future<JsonObject> jsonObjectFuture =
sut.fetchVendorDetailsVendorIdAsFuture(mockWebServer.url("/").toString(), new HashMap<>());
// then -----
final RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("GET", recordedRequest.getMethod());
assertEquals(1, mockWebServer.getRequestCount());
testContext.assertComplete(jsonObjectFuture)
.map(val -> {
assertEquals("{'futureCompleted': true}", val.encode());
testContext.completeNow();
return val;
})
.onComplete(onComplete -> {
assertTrue(onComplete.succeeded());
log.info("done");
})
.onFailure(onError -> Assertions.fail());
}
}
This test will of course need a little bit of customization to run in your project, but I hope it will give a picture on how to approach testing RxJava's futures.

Test POST request on PlayFramework 2.4.x

Good morning,
I'm trying to test some POST requests on my controllers.
I have no problems with GET request :
#Test
public void testGetAll() {
TestModel test = new TestModel();
test.done = true;
test.name = "Pierre";
test.save();
TestModel test2 = new TestModel();
test2.done = true;
test2.name = "Paul";
test2.save();
Result result = new controllers.ressources.TestRessource().get(null);
assertEquals(200, result.status());
assertEquals("text/plain", result.contentType());
assertEquals("utf-8", result.charset());
assertTrue(contentAsString(result).contains("Pierre"));
assertTrue(contentAsString(result).contains("Paul"));
}
But when I have to test a POST request, i can't give POST params to the controller.
here is the method I want to test :
public Result post() {
Map<String, String> params = RequestUtils.convertRequestForJsonDecode(request().queryString());
T model = Json.fromJson(Json.toJson(params), genericType);
model.save();
reponse.setData(model);
return ok(Json.prettyPrint(Json.toJson(reponse)));
}
I've try several solutions, but I can't find a proper one :
Try to use FakeRequest
Try to Mock the Http.Request object
So, what is the best way to write tests for my controllers ?
I'm using Play Framework 2.4.6 with Java.
Junit 4 and Mockito.
For tests of an POST action I use the RequestBuilder and the play.test.Helpers.route method.
For one with JSON data it could look like this (I use Jackson's ObjectMapper for marshaling):
public class MyTests {
protected Application application;
#Before
public void startApp() throws Exception {
ClassLoader classLoader = FakeApplication.class.getClassLoader();
application = new GuiceApplicationBuilder().in(classLoader)
.in(Mode.TEST).build();
Helpers.start(application);
}
#Test
public void myPostActionTest() throws Exception {
JsonNode jsonNode = (new ObjectMapper()).readTree("{ \"someName\": \"sameValue\" }");
RequestBuilder request = new RequestBuilder().method("POST")
.bodyJson(jsonNode)
.uri(controllers.routes.MyController.myAction().url());
Result result = route(request);
assertThat(result.status()).isEqualTo(OK);
}
#After
public void stopApp() throws Exception {
Helpers.stop(application);
}
}

405 Method Not Allowed with Spring

I have the following test for an HTTP endpoint:
public static final String DATA_PARAMETER = "data";
public static final String ID_PARAMETER = "id";
public static final String VIDEO_SVC_PATH = "/video";
public static final String VIDEO_DATA_PATH = VIDEO_SVC_PATH + "/{id}/data";
#Multipart
#POST(VIDEO_DATA_PATH)
public VideoStatus setVideoData(#Path(ID_PARAMETER) long id, #Part(DATA_PARAMETER) TypedFile videoData);
#Test
public void testAddVideoData() throws Exception {
Video received = videoSvc.addVideo(video);
VideoStatus status = videoSvc.setVideoData(received.getId(),
new TypedFile(received.getContentType(), testVideoData));
assertEquals(VideoState.READY, status.getState());
Response response = videoSvc.getData(received.getId());
assertEquals(200, response.getStatus());
InputStream videoData = response.getBody().in();
byte[] originalFile = IOUtils.toByteArray(new FileInputStream(testVideoData));
byte[] retrievedFile = IOUtils.toByteArray(videoData);
assertTrue(Arrays.equals(originalFile, retrievedFile));
}
I'm trying to implement the requirements defined by this test with the following endpoint defined in Swing:
#RequestMapping(method = RequestMethod.POST, value = "/video/{id}/data")
public void postVideoData(#PathVariable("id") long videoId,
#RequestParam("data") MultipartFile videoData) throws IOException {
if (videoId <= 0 || videoId > videos.size()) {
throw new ResourceNotFoundException("Invalid id: " + videoId);
}
Video video = videos.get((int)videoId - 1);
InputStream in = videoData.getInputStream();
manager.saveVideoData(video, in);
}
The problem is that I get a "405 Method Not Allowed" error. What am I doing wrong so that my POST method is not being recognized?
The problem is that the client interface expects a VideoStatus object returned from the server. I declared the method on the server side to return void.
I don't know if you already fix your problem, but I got the same error, because I am new with Retrofit too :).
The solution for me, was to put an Annotation to specify the response content type, in my case
#ResponseBody
Another change that I must did, was to change void for a custom status.
Hope this helps or at least gives you a light.
Rgds.
I had the same issue. RetroFit request calls must have either a return type or Callback as last argument.
So in the RetroFitted API:
#POST("/path")
public Void saveWhatever(#Body Whatever whatever);
Than in the controller it must be :
#RequestMapping(value = "/path", method = RequestMethod.POST)
public #ResponseBody Void saveWhatever(#RequestBody Whatever whatever) {
repository.save(whatever);
return null;
}

Jax RS PUT method - junit test

I have 3 methods below. The first one calls the second one and the second one calls the third. The junit test fails because all the methods are 'void', and I used an object to test junit.
public class Ids
{
#PUT
#Path("/{otherId}")
#Produces("application/xml")
//First method:
public Response putTag
(
#Context SecurityContext context
, #Context HttpServletRequest req
, #Context HttpServletResponse resp
, #PathParam("otherId") String otherId
, #FormParam("userId") String userId
) {
Map<String, String> obj = new Hashtable<String, String>();
obj.put("userId", userId);
obj.put("otherId", otherId);
putTagMethod(obj);
return ResponseBuilder.buildResponse("Inserted tag records", MediaType.APPLICATION_XML);
}
//Second Method
public void putTagMethod(Map<String, String> obj) {
String userId = obj.get("userId");
String entryId = obj.get("otherId");
try {
updateTag(userId, otherId);
} catch (java.sql.SQLException e) {
LOGGER.error("java.sql.SQLException: ", e);
e.printStackTrace();
}
}
//Third Method
public static void updateTag(String userId, String otherId) throws PersistenceException, {
if (...some condition) {
throw new InvalidParameterException("blah blah blah");
}
SpecialData data = null;
//Update if found, else insert
if (dataList != null && dataList.size() > 0) {
data = dataList.get(0);
update(userId, otherId);
} else {
insert(userId, otherId);
}
How do I write a Junit test to test 'Response putTag' method?
I wrote this (below) junit, but it gives error (
#Test
public void testPutTag() throws Exception
{
Ids tags = new Ids();
Map<String,String> obj = new HashMap<String,String>();
String xml = tags.putTag(obj);
assertTrue("PUT", xml.equals(
"<result>insert</result>"));
}
I'm getting error:
Incompatible types
required: Map<String, String>
found: void
problem is I need to assign 'xml' to a return type but all my methods are void.
How do I solve this?
Anyone please advise...

Categories