There are a couple of ways of integrating Spring with Wicket. If your WebApplications extends SpringWebApplication you already have access to the ApplicationContext for dependency retrieval. See this blog entry on how to proceed from there.
However in my case the WebApplication was extending AuthenticatedWebApplication and Spring beans were injected by adding a SpringComponentInjector to the ComponentInstantiationListener. Spring dependencies are then added by using the @SpringBean annotation.
So how to unit test pages using a @SpringBean annotation? Actually the solution ain’t that complex.
First of all in my main WebApplication I’ve moved registering the SpringComponentInjector to a seperate method:
public void init()
{
..
springInjection();
..
}
protected void springInjection()
{
addComponentInstantiationListener(new SpringComponentInjector(this));
}
For unit testing purposes I extended the WebApplication so I could provide a different injector and provided a method to retrieve the mock context:
public class TestEhourWebApplication extends EhourWebApplication
{
private AnnotApplicationContextMock mockContext;
@Override
protected void springInjection()
{
mockContext = new AnnotApplicationContextMock();
mockContext.putBean("EhourConfig", new EhourConfigStub());
addComponentInstantiationListener(new SpringComponentInjector(this, mockContext));
}
public AnnotApplicationContextMock getMockContext()
{
return mockContext;
}
}
AnnotApplicationContextMock is provided by Wicket and is quite a handy class as it allows you to register beans in the ApplicationContext on the fly.
Now with the TestWebApplication in place which uses a mock Spring context the only thing left is instantiating the WicketTester with this WebApp and fetching the AnnotApplicationContextMock from the WebApp so it’s available for unit tests. This is perfect stuff for a BaseTestCase:
public class BaseUITest extends TestCase
{
protected WicketTester tester;
protected AnnotApplicationContextMock mockContext;
protected void setUp() throws Exception
{
TestEhourWebApplication webapp = new TestEhourWebApplication();
tester = new WicketTester(webapp);
mockContext = ((TestEhourWebApplication)tester.getApplication()).getMockContext();
}
}
Any extending TestCases now have access to the Spring’s context and can register any beans needed for the page creation. For instance mocking a ConfigService dependency (using easymock):
public class MainConfigTest extends BaseUITest
{
public void testMainConfigRender()
{
ConfigurationService configService = createMock(ConfigurationService.class);
mockContext.putBean("configService", configService);
expect(configService.getConfiguration())
.andReturn(new EhourConfigStub());
replay(configService);
tester.startPage(MainConfig.class);
tester.assertRenderedPage(MainConfig.class);
tester.assertNoErrorMessage();
verify(configService);
}
}
et voila !
