I am not sure why PowerMockito.when returns null. This is my class under test:
public class A {
public Integer callMethod(){
return someMethod();
}
private Integer someMethod(){
//Some Code
HttpPost httpPost = new HttpPost(oAuthMessage.URL);
//Some Code
HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse httpResponse = httpClient.execute(httpPost); ------1
Integer code = httpResponse.getStatusLine().getStatusCode(); ---2
return code;
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({ MacmillanServiceImpl.class, PersonService.class, AuthorizeServiceImpl.class, ProvisionHelper.class, ESPHelper.class,
DPFServiceImpl.class, TransactionLogServiceImpl.class, HttpClient.class, HttpEntity.class, InputStream.class, IOUtils.class,
DTOUtils.class, MacmillanESPResponseDTO.class, HttpClientBuilder.class, CloseableHttpClient.class, HttpPost.class, IOUtils.class,
HttpResponse.class, CloseableHttpResponse.class, StatusLine.class })
#PowerMockIgnore({ "javax.crypto.*", "javax.net.ssl.*" })
public class TestA {
//Spying some things here & Injecting them
#Test
public void testA() {
HttpClient httpClientMock = PowerMockito.mock(HttpClient.class);
HttpClientBuilder httpClientBuilderMock = PowerMockito.mock(HttpClientBuilder.class);
CloseableHttpClient closeableHttpClientMock = PowerMockito.mock(CloseableHttpClient.class);
HttpResponse httpResponseMock = PowerMockito.mock(HttpResponse.class);
PowerMockito.mockStatic(HttpClientBuilder.class);
given(HttpClientBuilder.create()).willReturn(httpClientBuilderMock);
when(httpClientBuilderMock.build()).thenReturn(closeableHttpClientMock);
PowerMockito.when(httpClientMock.execute(httpPost)).thenReturn(httpResponseMock); --This does not work----Line 3
//Other codes
//call the method
}
In line-1 I get httpResponse as null. I want to get a mocked HTTPResponse object so that I can proceed further.
I have also tried this instead of Line 3:
CloseableHttpResponse closeableHttpResponse = PowerMockito.mock(CloseableHttpResponse.class);
PowerMockito.when(closeableHttpClientMock.execute(httpPost)).thenReturn(closeableHttpResponse);
Can anyone help me?
Seems that the issue is that the httpPost instance that you pass when mocking is not the same as the one you pass in the execution.
What you can do to resolve this is use Matchers.eq() when you mock, that way the when will be executed on every object equals to the one you pass:
PowerMockito.when(httpClientMock.execute(Matchers.eq(httpPost)))
.thenReturn(httpResponseMock);
Related
Suffered a lot in finding how to mock http response . Mocking http request for the same library was easy . Thought to create a thread here , to save your time should you need it .
Requirement ->
Wanted to mock a HttpResponse that is returned when any HttpRequest object is executed . (Note - this is specifically for google client api library)
//creating mockContent for httpRequest
MockHttpContent mockHttpContent = new MockHttpContent();
String content = new String("requestBody");
mockHttpContent.setContent(str.getBytes());
//mocking httpResponse and linking to httpRequest's execution
HttpTransport transport =
new MockHttpTransport() {
#Override
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
return new MockLowLevelHttpRequest() {
#Override
public LowLevelHttpResponse execute() throws IOException {
MockLowLevelHttpResponse result = new MockLowLevelHttpResponse();
result.setContent("responseBody");
result.setContentEncoding("UTF-8");//this is very important
result.setHeaderNames(List.of("header1","header2"));
result.setHeaderValues(List.of("header1","header2"));
return result;
}
};
}
};
HttpRequest httpRequest = transport.createRequestFactory().buildPostRequest(HttpTesting.SIMPLE_GENERIC_URL,mockHttpContent);
//getting httpResponse from httpRequest
httpResponse = httpRequest.execute();
//condition to verify the content (body) of the response
assertEquals("responseBody",IOUtils.toString(httpResponse.getContent()));
I just made a new Springboot Project and every time I want so implement the Controller for the Mapping from my API into my Database I get the statuscode 302.
The class I want to put into the db is a Movie, here is the Moviecontroller
#RestController()
#RequestMapping(path = "movie")
public class MovieController {
private final MovieService movieService;
#Autowired
public MovieController(MovieService movieService){ this.movieService = movieService; }
#GetMapping("getmovie")
public List<Movie> getMovie(){
return movieService.getMovie();
}
#PostMapping(path = "postmovie")
public void addNewMovie(#RequestBody Movie movie){
movieService.addNewMovie(movie);
}
}
The Class which handles the API has this method in it which is supposed to handle a Movie Json and send it via http to the Controller. Since I want to post the minimum code necessary for this Problem I do not post the complete class. The Route is...
#Route(value = "addmovie", layout = MainLayout.class)
public void saveMovieInDatabase(int movieId, String title, String posterSrc, int releaseDate,int length) throws IOException {
String movieString = new ObjectMapper().writeValueAsString(new Movie(movieId,title,posterSrc,releaseDate,length));
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("http://localhost:8080/movie/postmovie");
post.setEntity(new StringEntity(movieString));
post.setHeader("Accept","application/json");
post.setHeader("Content-type", "application/json");
CloseableHttpResponse response = client.execute(post);
System.out.println(response.getStatusLine().getStatusCode());
}
I've been trying to mock Apache HTTPClient with ResponseHandler, in order to test my service, using Mockito. The method in question is:
String response = httpClient.execute(httpGet, responseHandler);
where "responseHandler" is a ResponseHandler:
ResponseHandler<String> responseHandler = response -> {
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
return EntityUtils.toString(response.getEntity());
} else {
log.error("Accessing API returned error code: {}, reason: {}", status, response.getStatusLine().getReasonPhrase());
return "";
}
};
Can somebody suggest how can I accomplish this? I want to mock "execute()" method, but I don't want to mock the "responseHandler" (I wan't to test the existing one).
Thanks!
You can mock HttpClient and use Mockito's thenAnswer() method. For example, something like:
#Test
public void http_ok() throws IOException {
String expectedContent = "expected";
HttpClient httpClient = mock(HttpClient.class);
when(httpClient.execute(any(HttpUriRequest.class), eq(responseHandler)))
.thenAnswer((InvocationOnMock invocation) -> {
BasicHttpResponse ret = new BasicHttpResponse(
new BasicStatusLine(HttpVersion.HTTP_1_1, HttpURLConnection.HTTP_OK, "OK"));
ret.setEntity(new StringEntity(expectedContent, StandardCharsets.UTF_8));
#SuppressWarnings("unchecked")
ResponseHandler<String> handler
= (ResponseHandler<String>) invocation.getArguments()[1];
return handler.handleResponse(ret);
});
String result = httpClient.execute(new HttpGet(), responseHandler);
assertThat(result, is(expectedContent));
}
I am writing a Junit test with apache httpclient. The testCreate method successfully insert a record to the database but the status return is 500 which make the test case to fail.
Below is the test case,
public void testCreate() throws Exception {
String url = "http://localhost:8080/mediaactivity/videoAssignment";
HttpPost request = new HttpPost(url);
request.addHeader("Content-Type", "application/json");
request.addHeader("xAuthorization", "123");
request.addHeader("correlationId", "123");
String json = "{"+
"\"VideoType\": \"Sample\","+
"\"groupType\": \"INDIVIDUAL\","+
"\"submissionMethod\": \"test\","+
"\"title\": \"test me\""+
"}";
StringEntity entity = new StringEntity(json);
request.setEntity(entity);
// When
HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
// Then
assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_CREATED));
}
The controller looks like,
#RequestMapping(value = "/videoAssignment", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE, method = RequestMethod.POST)
#ResponseBody
public HttpEntity<VideoAssignment> createVideoAssingnment(
//#ApiParam are there..){
//other methods
return new ResponseEntity<>(va, HttpStatus.CREATED);
}
what i am missing here?
I am new to Android development. Here, I am making a GET call like this -
protected String doInBackground(String... params) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("email", "guest#example.com"));
JSONHttpClient jsonHttpClient = new JSONHttpClient();
ProductDetail[] products = jsonHttpClient.Get(ServiceUrl.PRODUCT, nameValuePairs, ProductDetail[].class);
return null;
}
This is the GET call in JSONHttpClient file -
public <T> T Get(String url, List<NameValuePair> params, final Class<T> objectClass) {
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Accept-Encoding", "gzip");
httpGet.setHeader("Authorization", "Bearer <code>");
HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
InputStream inputStream = httpEntity.getContent();
Header contentEncoding = httpResponse.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(inputStream);
}
String resultString = convertStreamToString(inputStream);
inputStream.close();
return new GsonBuilder().create().fromJson(resultString, objectClass);
}
return null;
}
And this is my ProductDetail class -
public class ProductDetail {
public int Id;
public String Name;
}
On running this, I am getting below error -
No-args constructor for class com.compa.ProductDetail does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
This is thrown on this line in JSONHttpClient file -
return new GsonBuilder().create().fromJson(resultString, objectClass);
Can anyone help on this?
In my web api, I am creating json like this (proddetails is a C# IEnumerable object) -
json = JsonConvert.SerializeObject(proddetails);
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
The structure of response json is -
[
{
"Id": 1,
"Name": "First"
},
{
"Id": 2,
"Name": "Second"
}
]
The Gson user guide (https://sites.google.com/site/gson/gson-user-guide) tells you that a well behaved class (meant for serialization and deserialization) should have a no argument constructor. If this is not there, it advises you to use InstanceCreator.
Even if you do not have a constructor, Gson will create an ObjectConstructor for your class. But this is not safe always and has it's own limitations. This question on SO goes more into the details: Is default no-args constructor mandatory for Gson?
NOTE: Please see that if this is an inner class, then it MUST have a constructor as explained in the documentation.
EDIT: Your json is an array. So you need to have the specified number of array objects in the containing class. So you can do the following and then cast:
public class ProductDetailArray {
public ProductDetailArray[] array;
public static ProductDetail {
public ProductDetail() {} // You can also make the constructor private if you don't want anyone to instantiate this
public int Id;
public String Name;
}
}
Once you cast your json similarly as before:
ProductDetailArray obj = GsonBuilder.create().fromJson(response, ProductDetailArray.class);
ProductDetail one = obj.array[0];
ProductDetail two = obj.array[1];
And then you can do your manipulation.. also you should probably be using Gson.fromJson() rather than the GsonBuilder