atom feed3 messages in net.java.dev.jersey.devRe: [Jersey] Spring unit testing with...
FromSent OnAttachments
James RussoMay 22, 2010 3:52 pm 
Paul SandozMay 24, 2010 1:59 am 
James RussoMay 24, 2010 5:24 am 
Subject:Re: [Jersey] Spring unit testing with Jersey test framework?
From:James Russo (jr@halo3.net)
Date:May 24, 2010 5:24:57 am
List:net.java.dev.jersey.dev

Hello Paul,

Thanks. I think that mocking objects is a great tool for independently testing
classes while removing the dependencies. My specific goal was to test a request
filter which verifies the validity of a header containing a cryptographically
signed token used to secure access to a restful API. The filter needs access to
a public key to verify the signature and this public key is obtained from a
class which that implements the EndpointConfigurationDAO interface. This
interface has a getConfiguration method which returns an EndpointConfiguration
object. I'm using EasyMock to mock-up this interface and return the
configuration object containing the public key. This filter was previously a
servlet filter, which I tested by calling the doFilter method using some Mock
httpRequest and httpResponse objects from the spring framework, but nothing like
that exists in Jersey so this wasn't possible. I looked into mocking up a
ContainerRequest object, but I didn't get very far.

I spent some more time on it this weekend and I now have a workable solution and
while It may not be very elegant it works. Here is how I accomplished it. I'm
open for any suggestions from others on how I might be able to improve it.

First, I use applicationContext to create my mock object by using the following
bean definition:

<bean id="EndpointConfigurationDAO" class="org.easymock.EasyMock" factory-method="createMock" lazy-init="false" autowire="byName"> <constructor-arg index="0" value="net.halo3.ipms.endpoint.dao.EndpointConfigurationDao" /> </bean>

This will create a EasyMock object implementing the EndpointConfigurationDAO
interface. The problem is getting this Mock object into my actual unit test
(after JerseyTest creates the applicationContext) so I can use it in the
individual test methods. So I basically needed access to the applicationContext
which was created by the JerseyTest framework. To make this happen I created
another simple class and bean definition:

<bean id="applicationContextHolder"
class="net.halo3.ipms.endpoint.security.SpringContextHolder" />

The SpringContextHolder is a simple class which implements the
ApplicationContextAware interface so that it will be provided the
applicationContext once it is created. I store this ApplicationContext in a
static class variable that I can then access from the JUnit test. Using this
applicationContext I can obtain my mocked object and work on it.

EndpointConfigurationDao dao = (EndpointConfigurationDao)
SpringContextHolder.applicationContext .getBean("EndpointConfigurationDAO");

and then work with it via EasyMock methods. (ie:
EasyMock.expect(dao.getEndpointConfiguration()).andReturn(new
EndpointConfiguration());

Hopefully this makes sense to everyone. Like I mention, my main problem was
getting access to an object created by the applicationContext which was created
by the JerseyTest class. Another solution would have been to create a concrete
"test" object which implemented the EndpointConfigurationDAO interface and use
static methods to set the EndpointConfiguration object returned. Having this
test object wired up in the applicationContext. However, I think that would be
practical only in this simple case. If you have a more complex interaction using
a mocking framework is the way to go so that you keep the operation of the
object under test and its interactions with dependencies in the same junit
method.

Take care,

-jr

On May 24, 2010, at 5:00 AM, Paul Sandoz wrote:

Hi James,

I am skeptical of the value of using Mocking techniques for testing, plus i am
not all that familiar with specifics of say EasyMock.

The approach we have encouraged is to utilize an embedded solution like Grizzly
and then the unit tests become more like functional tests.

However, currently in Jersey it is hard to override Jersey/JAX-RS-related
injected dependencies unless you directly instantiate the class you want to test
and perform the injection yourself, which is easier if you are using constructor
injection, but becomes harder if another DI framework is utilized.

If you can explain what you want to do with code i might be able to help more.
Also if there are other developers interested in using mocking and have more
experience maybe we can work together to come up with a solution?

On May 23, 2010, at 12:53 AM, James Russo wrote:

Hello,

I'm looking to test some Jersey Resources which also have some @Autowired
dependencies. I'd like to use the Jersey Test framework and something like
EasyMock. However in my trying to get this to work I'm not sure how it is
possibles since one context will belong to Grizzly and one context will belong
to the unit test being run? I need access to the mock objects in the unit test
to define the order of methods and return data, and then the same mock object in
the resource object so it can call those methods?

Is this even possible? Seem like I would need to both use something like
SpringJUnit4ClassRunning as well as passing the context to the WebAppDescriptor
in JerseyTest class.

Thanks,

-jr