I have a web application, that contains a configuration xml file for one of my application services that is exposed as spring bean. Also I have a standalone java application
I ended up using Spring MockServletContext class and injecting it directly to my service bean, before the test runs, as my service implemented ServletContextAware
:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test-ctx.xml" } )
public class SomeServiceTest {
@Autowired
private MyServletContextAwareService myService;
@Before
public void before(){
//notice that I had to use relative path because the file is not available in the test project
MockServletContext mockServletContext = new MockServletContext("file:..//src/main/webapp");
myService.setServletContext(mockServletContext);
}
If I had several classes using Servlet Context, then the better solution would be to use WebApplicationContext instead the default one (currently provided by DelegatingSmartContextLoader), but it would require implementing custom ContextLoader class and passing its class name to @ContextConfiguration annotation.
alternative and somewhat cleaner solution which later came to my mind is to refactor the service and inject ServletContext
via @Autowired
instead of messing with ServletContextAware
, and provide the bean of corresponding type(effectively a MockServletContext
instance).
Possibly, in future the direct support of MockServletContext
from test classes will be added to Spring see SPR-5399 and SPR-5243.
UPDATE FOR SPRING 3.2
In Spring 3.2 initialization of the servlet context became as simple as adding one @WebAppConfiguration
annotation:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("file:..//src/main/webapp")
@ContextConfiguration(locations = { "/test-ctx.xml" } )
public class SomeServiceTest {
see details in the article