Wicket and Spring JUnit Test

Just had a hard time to create a Junit Test with Wicket, Spring and Mockito. Finally I succeeded and want to share the solution.

The usecase is simple: a test if rendering of the homepage succeeds. The tricky part was the instantiation of the real Wicket Webapplication ( not a MockWebapplication ) with the Spring Context. Without any special arrangements instantiation of the Webapplication led to the following stacktrace:

java.lang.IllegalStateException: 
No WebApplicationContext found: no ContextLoaderListener registered? 
at org.springframework.web.context.support.WebApplicationContextUtils.
getRequiredWebApplicationContext(WebApplicationContextUtils.java:90)

To bypass this I override the method getServletContext in the WicketApplication and give Spring what it needs. This way i can test Wicket pages with Spring and using mocks with Mockito.

@RunWith(MockitoJUnitRunner.class)
public class TestHomePage
{
	private WicketTester tester;


	private YourWicketApplication app;

	@Mock
	private Service aService;

	@Before
	public void setUp() throws IOException, Exception
	{
		MockitoAnnotations.initMocks(this);
		tester = new WicketTester(app = new YourWicketApplication(){
                        
      /**
			 * adjust the servletcontext to contain a WebApplicationContext
			 */
			@Override
			public ServletContext getServletContext() {
				ServletContext servletContext = super.getServletContext();
				XmlWebApplicationContext  applicationContext = new XmlWebApplicationContext();
				applicationContext.setConfigLocation("classpath:applicationContext.xml");
				applicationContext.setServletContext(servletContext);
				applicationContext.refresh();
				servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);

				return servletContext;
			}

		});

    // replace spring bean with a mock
		app.setService(aService);

		Serializer serializer = new Persister();
		ListOfStuff list = serializer.read(ListOfStuff.class, new ClassPathResource("listofstuff.xml").
                getInputStream());

		when(aService.getList()).thenReturn(list);
	}

	@Test
	public void homepageRendersSuccessfully()
	{
		//start and render the test page
		tester.startPage(HomePage.class);

		//assert rendered page class
		tester.assertRenderedPage(HomePage.class);
		verify(aService).getList();
	}
}

Brix, a CMS framework

In nearly all web applications there is always some content component a site maintainer wants control over. From a minimal simple explanation on the homepage what the application is all about to content-driven sites like tweakers.net where content is the main component. For the latter category there are excellent CMS tools like Drupal and Joomla.

Tools for simple content requirements for a web application are hard to find, especially for Java. Therefore I was pleasantly surprised to learn of Brix, a Wicket-based CMS framework. Leveraging the Wicket framework, which has a clear separation of static- and dynamic behavior in the front-end layer, Brix enables you to mix static content with complex application logic in your own custom CMS-application. Here I will introduce the elements of the Brix and their meaning.

Brix

Brix is a Google-code project which recently reached their first release. Using Apache Wicket and Jackrabbit it consists of a core and multiple plugins (figure 1).

figure 1

These plugins can be plugged in by registering them at startup at the ‘Extension Point Registry’ in your code (example 1). The state of the site is persisted in a JCR repository, a ‘Workspace’. With the Snapshot plugin you can make a backup of the current state of the site. Brix Core contains a standard AdminPanel which glues all plugins together in a view. See figure 2 for a screenshot of this view.

figure 2 admin panel

The project also contains a demo application (brix-demo) which
demonstrates the use of the framework. It is the best place to start to gain experience with Brix. To get started with the demo follow the instructions on the ‘Running the demo‘ wiki page of Brix.

Build a site with Brix

Here I will go further into detail how you can use Brix to build a site.

Site Plugin

The site plugin is the central place to create your site. Here you can add resources as css files, create new pages, new folders and new templates. In the left panel you can navigate to each resource, page or template you have and edit it to your needs. Pages and templates have a content- and page preview, where the latter shows how the page or template looks like when rendered. Editing a page gives you the ability to write HTML in three different modes including a rich content editor were knowledge of HTML is not required.

Tiles

Tiles are building blocks you can add to a page. There a three different types of Tiles. Page Tiles, Menu Tiles and Custom Tiles. Page Tiles offers the ability to reuse the content of a page in another page. Menu tiles refer to menus, see ‘Navigation’ part below for more info.

Custom tiles require the implementation of the Tile interface and the extension of the TileEditorPanel. Custom Tiles offers a way to extend your application with some custom application logic. Custom Tiles have to be, like plugins,¬† registered at the ‘Extension Point Registry’ on startup (example 1). How to build a custom Tile will be discussed in a later post.

example 1:registering plugins and tiles at startup. 

public CMSBrix(BrixConfig config)
{
super(config);
// register plugins
config.getRegistry().register(Plugin.POINT, new MenuPlugin(this));
config.getRegistry().register(Plugin.POINT, new SnapshotPlugin(this));
config.getRegistry().register(Plugin.POINT, new PrototypePlugin(this))
config.getRegistry().register(Plugin.POINT, new WebdavUrlPlugin());
// register tiles;
config.getRegistry().register(Tile.POINT, new SurveyTile())
....

To add a Tile to a page you select the tile type you want and appoint an identifier to it. With the brix tag <brix tile id=”[identifier]“/> you can add it to the page.

Templates

Another element to build a page are templates. Templates can be used to hold common page elements like a header or footer. Templates can be extended by other templates. You can appoint a template to a page. Templates should contain the <brix:content/> tag, which at rendering is replaced by the page content. Together with tiles, templates are giving you a fine grained option to compose pages (figure 3).


figure 3 composing pages

Navigation

The menu plugin makes it possible to create menus with references to other pages. The menu plugin is represented by the ‘Menu’ tab in the AdminPanel. Here you can create a menu with the desired titles and references to pages for those titles. A menu is for a page just a Tile. At a specific page or template where you want the menu displayed, create a menu-tile and select the menu-name you have given to the previously created menu. For styling you can add CSS-classes to selected items. Add a <brix:tile id=[menutile-id]/> tag to the template or page with the name you have given to this menu-tile. This results in a page or template with navigation to other pages.

Conclusion

The Brix framework gives you the ability to create a custom CMS. Brix offers ready out-of-the-box components as templates and pages to satisfy your content needs and extension points like custom Tiles to mixin some custom behavior. With the available AdminPanel content can be created and altered.

Because it uses Apache Wicket it can be easily integrated into an existing Wicket web application. This open up an easy way to construct  web applications with custom logic which also offers plain content creation.

XPath for attribute value

After struggling with attributes for a long time, I finally discovered the easy way to obtain the text value of an attribute in a XML file with a XPath expression. Let’s say you got the following XML-file

<messages>
  <note id="501">
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
  </note>
  <note id="502">
    <to>Jani</to>
    <from>Tove</from>
    <heading>Re: Reminder</heading>
    <body>I will not</body>
  </note>
</messages>

To get the value of the id attribute of the first note use an Xpath-expression with a string function

[ string( //note[1]/@id ) ]
and you get 501.