Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

Magnolia uses JUnit 4 and if dynamic mocks are required Mockito (new) for creating unit tests. Before we were using EasyMock for dynamic mocks.

Mockito is a more recent mocking library. We'll not bulk convert existing EasyMock-Tests as this would be to big an effort. Instead we set up the following rules:

  • all new tests requiring dynamic mocks use Mockito
  • whenever you touch (fix, adapt, complete) an existing test that's using EasyMock: convert it to Mockito

Independently from that make sure your tests match our conventions. Information on how to best migrate JUnit3-style tests to JUnit4 can be found here.

Magnolia Provided Testing Support

In general we try to use the slimmest possible approach in tests. For testing basic functionality that does depend on itself there is no need to use mock objects. We can just test that method functionality straight away.

In cases we need to test objects that depend on other objects and this is where we use mock objects. Beware that they can just return what you want but the code behind won't be executed.

Imagine you need to test something that depends on a repository, well you can 'mock' a repository and it's content without having to create the repository itself.

Code Block
MockSession session = SessionTestUtil.createSession("testWorkspace", propertiesString);

By doing this you can access to the nodes of you 'fake' repositoy as if it where real. But if you really need to use a real repository you can extend from RepositoryTestCase and use the methods declared in it.

Useful classes included in magnolia-core for building tests:

Here are some of the clases we have for Magnolia testing, you can find more classes in package info.magnolia.test 

TypeRemark
ComponentsTestUtil

Set default implementations or instances when IoC can't be used yet.

MgnlTestCaseSets up a basic environment for the test, loads beans and modules properties and initializes a mock context as the local context.
RepositoryTestCaseSuperclass for Tests requiring access to a real jcr repo.
MockUtilUtil to create mock objects - especially MockContexts.
MockContextContext where you can add Sessions and set a User
MockNodeMock implementation of a jcr Node
MockContentMockImplemenation of a Content

 

What to choose when

Here's a few examples that should help to understand what approach should preferably be used in what situation:

General SetupSpecificsPreferred ApproachExample
Class under tests operates on JCR Nodefew calls to common methods of the NodeMockNode if it supports those calls, Mockito mock else 
 need a simple hierarchy of NodesMockNode if it supports those calls, Mockito mock else 
 need a simple hierarchy of Nodes but with several propertiesuse SessionTestUtil to instantiate MockSession + MockNodes from propertiesStream or String 
 need a complex hierarchy of Nodes, real NodeTypes or issue real queriesuse RepositoryTestCase 

 

Resources

Mock Object: http://en.wikipedia.org/wiki/Mock_object

Mockito Documentation: http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html

Mockito Examples: http://gojko.net/2009/10/23/mockito-in-six-easy-examples/