final HttpResponse response = this.call(queryUri);
entity = response.getEntity();public HttpResponse call(final URI queryUri) throws Exception
{
Future<HttpResponse> futureResponses = executor.submit(new Callable<HttpResponse>()
{
#Override
public HttpResponse call() throws Exception
{
final HttpGet httpget = new HttpGet(queryUri);
return httpclient.execute(httpget);
}
});
return futureResponses.get(A9_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
}
final HttpResponse response = this.call(queryUri);
entity = response.getEntity();
parse(entity.getcontent());
wondering how do I mock all the object, can someone provide me the workable code on test class?
I would recommend that you pull out the creation of the Callable to a protected method.
public Callable<HttpResponse> createCallable(String queryUri){
return new Callable<HttpResponse>(){
#Override
public HttpResponse call() throws Exception
{
final HttpGet httpget = new HttpGet(queryUri);
return httpclient.execute(httpget);
}
});
}
I don't think you actually need EasyMock for this test. In fact it might be easier without it. In your test you can override this method to return a test stub. I think if the get times out, then it will throw a TimeoutException and not actually cancel the job. So I think you just need to catch TimeoutException to make sure everything works.
So maybe your mock just has to sleep for A9_CALL_TIMEOUT plus some additional fudge factor.
#Test
public void testTimeout(){
Subclass sut = new Subclass(){
#Override
public Callable<HttpResponse> createCallable(String queryUri){
return new Callable<HttpResponse>(){
#Override
public HttpResponse call() throws Exception{
try{
Thread.sleep(A9_CALL_TIMEOUT *2);
catch(InterruptException e) {}
}
});
};
//you can also use Junit ExpectedException rule instead
// of the try catch here
try{
sut.runQueryMethodWithExecutor();
fail("should throw timeout");
}catch(TimeoutException e){
//expected
}
}
Related
Is there any way to test this using JUnit and Mockito?
Below is a method that I want to test
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logoutPage(HttpServletRequest request, HttpServletResponse response)
{
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null)
{
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login?logout";
}
Test for logout
#Test
public void testLogoutPage() throws Exception
{
MockHttpServletRequestBuilder requestBuilder = get("/logout");
MockMvcBuilders.standaloneSetup(this.loginController)
.build()
.perform(requestBuilder)
.andExpect(status().isFound())
.andExpect(MockMvcResultMatchers.model().size(0))
.andExpect(view().name("redirect:/login?logout"))
.andExpect(MockMvcResultMatchers.redirectedUrl("/login?logout"));
}
Test covers everything except.
new SecurityContextLogoutHandler().logout(request, response, auth);
I tried some assertions, but always get NullPointerException.
private static String getToken(HttpClient clientInstance) throws badcredentailsexception{
try{
// some process here throws IOException
}
catch(IOexception e){
throw new badcredentailsexception(message, e)
}
}
Now I need to write Junit test for the above method, My Junit code for above function is below
#Test(expected = badcredentailsexception.class)
public void testGetTokenForExceptions() throws ClientProtocolException, IOException, NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Mockito.when(mockHttpClient.execute(Mockito.any(HttpPost.class))).thenThrow(IOException.class);
// mocked mockHttpClient to throw IOException
final Method method = Client.class.getDeclaredMethod("getToken", HttpClient.class);
method.setAccessible(true);
Object actual = method.invoke(null, mockHttpClient);
}
But this test is not being passed, any improvements??
Can we check the exception thrown by private method from junit ??
First of all, it is an antipattern to test a private method. It is not part of your API. See the already linked question: Testing Private method using mockito
To answer your question: When invoking a method via Reflection and the invoked method throws an Exception, the Reflection API wraps the Exception into an InvocationTargetException. So you could catch the InvocationTargetException and inspect the cause.
#Test
public void testGetTokenForExceptions() throws Exception {
HttpClient mockHttpClient = mock(HttpClient.class);
when(mockHttpClient.execute(any(HttpPost.class))).thenThrow(IOException.class);
Method method = Client.class.getDeclaredMethod("getToken", HttpClient.class);
method.setAccessible(true);
try {
method.invoke(null, mockHttpClient);
fail("should have thrown an exception");
} catch (InvocationTargetException e) {
assertThat(e.getCause(), instanceOf(BadCredentialsException.class));
}
}
You couldn't test private methods with JUnit or even with Mockito framework.
You could find more details in this question: Testing Private method using mockito
If you really need to test this private method, you should use PowerMock framework.
I have a Spring Boot Filter that I'm using to authenticate using Jwt. If successful, everything works great and I send out a Json response of my design. However, if the Authorization header is missing or incorrect, I throw a ServletException with a custom message. This results in an ugly Json that looks like this:
{
"timestamp":1453192910756,
"status":500,
"error":"Internal Server Error",
"exception":"javax.servlet.ServletException",
"message":"Invalid Authorization header.",
"path":"/api/test"
}
I wish to customize this Json so it takes the standard form I'm using for all my other responses.
My Filter code is here:
public class JwtFilter extends GenericFilterBean {
#Override
public void doFilter(final ServletRequest req,
final ServletResponse res,
final FilterChain chain) throws IOException, ServletException {
System.out.println("JwtFilter");
final HttpServletRequest request = (HttpServletRequest) req;
final String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
throw new ServletException("Missing Authorization header.");
}
if (!authHeader.startsWith("Bearer ")) {
throw new ServletException("Invalid Authorization header.");
}
final String token = authHeader.substring(7);
try {
final Claims claims = Jwts.parser().setSigningKey("secretkey")
.parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
}
catch (final SignatureException e) {
throw new ServletException("Invalid token.");
}
chain.doFilter(req, res);
}
}
I tried using a wrapper to wrap the response but that didn't work. Another SO post said the response was not changeable but that wouldn't even make sense.
I think the correct way would be to edit the ServletResponse res but I couldn't get it to work.
Thanks!
EDIT: Kind of hacky but it works. If there's a better way, please answer:
public class JwtFilter extends GenericFilterBean {
#Override
public void doFilter(final ServletRequest req,
final ServletResponse res,
final FilterChain chain) throws IOException, ServletException {
System.out.println("JwtFilter");
final HttpServletRequest request = (HttpServletRequest) req;
final String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Missing Authorization header."));
return;
}
if (!authHeader.startsWith("Bearer ")) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Invalid Authorization header."));
return;
}
final String token = authHeader.substring(7);
try {
final Claims claims = Jwts.parser().setSigningKey("secretkey")
.parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
}
catch (Exception f) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Invalid token."));
return;
}
chain.doFilter(req, res);
}
}
In general, wrapping the response and then modifying the response output stream after the call to doFilter is the correct approach, e.g.
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
CharArrayWriter caw = new CharArrayWriter();
caw.write("your json");
response.setContentLength(caw.toString().getBytes().length);
out.write(caw.toString());
out.close();
Taken from Oracle JavaEE 5 Tutorial
Nevertheless, your usecase seems more appropriate for being dealt with in a RestController handler method, possibly in conjunction with an #ExceptionHandler(ServletException.class) annotated method. This would be a more generic approach that allows you to harness the power of Spring's content negotiation to deal with the JSON serialization.
While implementing a File Uploader controller in Spring MVC I stucked with one problem. My code snap is given below.
#Controller
public class FileUploader extends AbstractBaseController implements HandlerExceptionResolver
{
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseBody
public JSONObject handleFileUpload(#RequestParam("file") MultipartFile file)
{
JSONObject returnObj = new JSONObject();
if (file.isEmpty())
{
returnObj.put("success", "false");
returnObj.put("message", "File is empty");
}
else
{
try
{
//my file upload logic goes here
}
catch (Exception e)
{
returnObj.put("success", "false");
returnObj.put("message", "File not uploaded.");
}
}
return returnObj;
}
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object obj, Exception exception)
{
ModelAndView model = new ModelAndView();
Map map = new HashMap();
if (exception instanceof MaxUploadSizeExceededException)
{
// I want to return JSONObject from here like given below.
/**
* { "message":"File size exceeded", "success":"false" }
* */
map.put("message", "File size exceeded");
map.put("success", "false");
model.addObject(map);
}
return model;
}
}
and my spring configuration look likes
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<property name="maxUploadSize" value="300000"/>
</bean>
now In my controller I want to return JSONObject instead of ModelAndView in resolveException method in my controller as given in code snap because I am developing some like REST method to upload file.
any ideas?
Thanks
If you use the Spring 3.2 above, I recommend this way.
At first, declare the ControllerAdvice.
#Controller
#ControllerAdvice
public class JAttachfileApi extends BaseApi
And make the Exception Handler to response JSON Object as following.
#ExceptionHandler(MaxUploadSizeExceededException.class)
public #ResponseBody Map<String,Object> handleMaxUploadSizeExceededException(
MaxUploadSizeExceededException ex)
{
Map<String,Object> result = getResult();
JFileUploadJsonResponse errorResult = new JFileUploadJsonResponse();
errorResult.setError("Maximum upload size of "+ex.getMaxUploadSize()+" bytes exceeded.");
List<JFileUploadJsonResponse> resultData = new ArrayList<JFileUploadJsonResponse>();
resultData.add(errorResult);
result.put("files", resultData);
return result;
}
You simply can annotate the method resolveException as #ExceptionHandler() and then you can have its signature like any other controller method. So placing #ResponseBody before the return type should work.
"Much like standard controller methods annotated with a #RequestMapping annotation, the method arguments and return values of #ExceptionHandler methods can be flexible. For example, the HttpServletRequest can be accessed in Servlet environments and the PortletRequest in Portlet environments. The return type can be a String, which is interpreted as a view name, a ModelAndView object, a ResponseEntity, or you can also add the #ResponseBody to have the method return value converted with message converters and written to the response stream."
I am in the process of rewriting a bottle neck in the code of the project I am on, and in doing so I am creating a top level item that contains a self populating Ehcache. I am attempting to write a test to make sure that the basic call chain is established, but when the test executes it hands when retrieving the item from the cache.
Here are the Setup and the test, for reference mocking is being done with Mockito:
#Before
public void SetUp()
{
testCache = new Cache(getTestCacheConfiguration());
recordingFactory = new EntryCreationRecordingCache();
service = new Service<Request, Response>(testCache, recordingFactory);
}
#Test
public void retrievesResultsFromSuppliedCache()
{
ResultType resultType = mock(ResultType.class);
Response expectedResponse = mock(Response.class);
addToExpectedResults(resultType, expectedResponse);
Request request = mock(Request.class);
when(request.getResultType()).thenReturn(resultType);
assertThat(service.getResponse(request), sameInstance(expectedResponse));
assertTrue(recordingFactory.requestList.contains(request));
}
private void addToExpectedResults(ResultType resultType,
Response response) {
recordingFactory.responseMap.put(resultType, response);
}
private CacheConfiguration getTestCacheConfiguration() {
CacheConfiguration cacheConfiguration = new CacheConfiguration("TEST_CACHE", 10);
cacheConfiguration.setLoggingEnabled(false);
return cacheConfiguration;
}
private class EntryCreationRecordingCache extends ResponseFactory{
public final Map<ResultType, Response> responseMap = new ConcurrentHashMap<ResultType, Response>();
public final List<Request> requestList = new ArrayList<Request>();
#Override
protected Map<ResultType, Response> generateResponse(Request request) {
requestList.add(request);
return responseMap;
}
}
Here is the ServiceClass
public class Service<K extends Request, V extends Response> {
private Ehcache cache;
public Service(Ehcache cache, ResponseFactory factory) {
this.cache = new SelfPopulatingCache(cache, factory);
}
#SuppressWarnings("unchecked")
public V getResponse(K request)
{
ResultType resultType = request.getResultType();
Element cacheEntry = cache.get(request);
V response = null;
if(cacheEntry != null){
Map<ResultType, Response> resultTypeMap = (Map<ResultType, Response>) cacheEntry.getValue();
try{
response = (V) resultTypeMap.get(resultType);
}catch(NullPointerException e){
throw new RuntimeException("Result type not found for Result Type: " + resultType);
}catch(ClassCastException e){
throw new RuntimeException("Incorrect Response Type for Result Type: " + resultType);
}
}
return response;
}
}
And here is the ResponseFactory:
public abstract class ResponseFactory implements CacheEntryFactory{
#Override
public final Object createEntry(Object request) throws Exception {
return generateResponse((Request)request);
}
protected abstract Map<ResultType,Response> generateResponse(Request request);
}
After wrestling with it for a while, I discovered that the cache wasn't being initialized. Creating a CacheManager and adding the cache to it resolved the problem.
I also had a problem with EHCache hanging, although only in a hello-world example. Adding this to the end fixed it (the application ends normally).
CacheManager.getInstance().removeAllCaches();
https://stackoverflow.com/a/20731502/2736496