REST integration Tests with Java and Junit

731 views
Skip to first unread message

Christopher Armstrong

unread,
Aug 19, 2012, 8:54:40 AM8/19/12
to google-a...@googlegroups.com
Hello,

I'm currently developing an application in Java and want to use AppEngine. My setup uses Jersey JSON/REST to exchange data between the client and the server.

I would like to do following in the development mode with JUnit:
* Start AppEngine
* Execute Tests
* Stop AppEngine

I have had two threads open on Stackoverflow. First thread was how I can start AppEngine over Junit without spawning threads so that I can test my REST resources. I have been told that this is an integration test and Junit can't be used for that. I should try to test by executing the methods of the resource class directly. Ok, I was thinking but it is somehow funny because when reading the Jersey docs they suggest exactly this. Starting a webserver to test the REST resources with Junit.

I tried then to execute the methods directly and this worked at least for the getStatus() method from the Response class. But when I execute the methods directly and want to use getEntity() method of the Response class I can't marshal the object back in to the entity class. So this isn't working either out of some reason and I'm unable get the created record back so that I have the contents.

Is there any best practice provided by Google to test REST interfaces in an automated manner or does anybody know how to test jersey resource classes properly (without curl on the command line)?

Its nice that I'm doing it all wrong and that Junit has nothing to do with Integration testing but somehow I need to test my classes. It would be great if somebody could give me a hint.

Thanks,
Chris

alex

unread,
Aug 19, 2012, 1:43:34 PM8/19/12
to google-a...@googlegroups.com
I never used Jersey but what we're doing in this kind of testing is simply mocking (HttpServletRequest)request.getInputStream() and a couple other methods  so that they would operate on payloads provided within the unit tests or files on a disk, and (mocked) Response would write to a string (instead of real HTTP communication). 

Nice thing about this is the tests are run really fast as no external processes (e.g. dev server) are launched during testing. Plus, Testbed is always available  in case there's a need to check some internal states. Also, the only external lib dependency (testing-wise) with which we mock classes like HttpServletResponse is Mockito.

Christopher Armstrong

unread,
Aug 19, 2012, 3:26:23 PM8/19/12
to google-a...@googlegroups.com
Hi Alex,

Thanks for your valuable input. I'll take a look at Mockito.

Kind regards,
Chris

alex

unread,
Aug 19, 2012, 4:10:34 PM8/19/12
to google-a...@googlegroups.com
I think you can do it with pretty much any mock framework, but to give you an idea of what I mean in the prev. msg:

ServletInputStream stream = new MockInputStream(some_bytes_or_string_data);
request = mock(HttpServletRequest.class);
when(request.getInputStream()).thenReturn(stream);
when(request.getServletPath()).thenReturn(some_path);
...

response = mock(HttpServletResponse.class);
output = new StringWriter();
when(response.getWriter()).thenReturn(new PrintWriter(output));

- MockInputStream is really just a ServletInputStream only that it takes a string (fake request data) as a constructor param.
- mocking getWriter() is just an sample I've taken from one of our app where I know it always uses getWriter(), otherwise I'd mock other methods.

The above would be defined somewhere a BaseTest class, so our tests really boil down to something like:

public void testSomething() {
  resp = get("/some/path?query=goes&here=too")
  // or post(payload)

  // do something with resp, 
  // e.g. make assertions 
}

Maybe there's a better way but the idea above works pretty well for us.

Christopher Armstrong

unread,
Aug 19, 2012, 4:39:09 PM8/19/12
to google-a...@googlegroups.com
Hi Alex,

Thanks for the example. This helps as I'm new to Mocking. Now I know what I'll be doing Monday evening :)

Kind regards,
Chris

Takashi Matsuo

unread,
Apr 9, 2013, 6:27:19 PM4/9/13
to google-a...@googlegroups.com

Hi Christopher,

The jersey test framework spawns a new thread and run a servlet container for your tests, so that it doesn't work well with App Engine's test helpers. I also recommend you write real unit tests against your Jersey resources, as Alex's recommendation.

Fortunately, now we have complete example for it. I've just written a sample which contains some unit tests against jersey resource classes. The sample is available at:

What I've done is basically the same as Alex suggested. The project also includes unit tests for client side javascript , and end to end tests with Angularjs testing framework. Please take a look if you're interested in.

-- Takashi

--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-appengine/-/buJYfYz-dfUJ.

To post to this group, send email to google-a...@googlegroups.com.
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.



--
Takashi Matsuo | Developers Programs Engineer | tma...@google.com

Christopher Armstrong

unread,
Apr 9, 2013, 7:18:35 PM4/9/13
to google-a...@googlegroups.com

Hi Takashi,

Thanks for your example and for your answer. It's appreciated.

Kind regards,
Chris

You received this message because you are subscribed to a topic in the Google Groups "Google App Engine" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-appengine/ePhCRl2CNeE/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to google-appengi...@googlegroups.com.

To post to this group, send email to google-a...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages