This question is a follow on from a previous question Specify Custom Application Context.
We are migrating some of our data services from Jersey 1.x using jersey-spring to Jersey 2.x using jersey-spring3.
We have a few test classes that inherit from JerseyTest. Some of these classes use custom applicationContext.xml files that are not specified in the web.xml file.
For object mocking purposes we would mock out some components in our Jersey Resources.
In Jersey 1.x we could mock objects in the application context file by
<bean id="mockBean" class="org.easymock.EasyMock"
factory-method="createStrictMock" autowire="byName">
<constructor-arg index="0" value="com.xxx.xxx.ClassToMock" />
</bean>
and retrieve these mocked instances as follows
ClassToMock obj = (ClassToMock)ContextLoader
.getCurrentWebApplicationContext()
.getAutowireCapableBeanFactory()
.getBean("mockBean");
How can the same be achieved with Jersey 2.x using jersey-spring3?
I have combed through the API docs, user guides and some of the sources but was unable to find an answer.
Thank you.
EDIT:
We will be using the mocked beans inside of our JAX-RS resources. We have service interfaces that are @Autowired
into our resources.
e.g.
@Path(ProductResource.RESOURCE_PATH)
@Component
@Scope("prototype")
public class ProductResource
extends GenericResource<Product, BaseModel> {
/*
* Members
*/
public static final String RESOURCE_PATH = "product/";
@Autowired
protected ProductService productService;
...
We want to mock out the and set the expectations on these services.
e.g.
<bean id="productService" class="org.easymock.EasyMock"
factory-method="createStrictMock">
<constructor-arg index="0"
value="com.xxx.xxx.service.ProductService" />
</bean>
Note: I am not a Spring expert and I consider this to be rather a work-around than a recommended approach. Hopefully someone will come up with a better solution.
You can't obtain an ApplicationContext
instance by calling ContextLoader#getCurrentWebApplicationContext()
because Jersey 2.x runtime is by default initialized outside of a Servlet container when using Jersey Test Framework (JerseyTest
) for unit/e2e tests.
In this case you need to use a little work-around to obtain an ApplicationContext
by implementing an ApplicationContextAware interface in your test package:
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtils.applicationContext = applicationContext;
}
}
Once you have this class, don't forget to mention it in your application context descriptor:
...
<bean class="org.glassfish.jersey.examples.helloworld.spring.ApplicationContextUtils" />
...
And you can use it in your tests:
public class JerseySpringResourceTest extends JerseyTest {
// ... Configure ...
@Before
public void mockUp() throws Exception {
// ApplicationContext is ready in your @Before methods ...
assertThat(ApplicationContextUtils.getApplicationContext(), notNullValue());
}
@Test
public void testJerseyResource() {
// ... as well as in your test methods.
assertThat(ApplicationContextUtils.getApplicationContext(), notNullValue());
}
}
Note: If you want to deploy your application to a Servlet container and run your (JerseyTest
) tests against it, consult Jersey Test Framework chapter in the Users Guide (especially External container section).
You can inject your test class to Jersey context if you don't have any objections for that.
For example:
@Override
protected Application configure() {
final TestJerseyApplication application = new TestJerseyApplication();
final Map<String, Object> properties = new HashMap<>();
properties.put("contextConfigLocation", "classpath:test-spring-context.xml");
application.setProperties(properties);
application.register(this);
return application;
}
After that the @Autowired
annotation will work for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With