Page History
Introduction
Magnolia uses JUnit 4 tests and Mockito
...
(new)
...
for
...
creating
...
unit
...
tests.
...
Before
...
we
...
were
...
using
...
EasyMock
...
for
...
dynamic
...
mocks.
...
Independently
...
from
...
that
...
make
...
sure
...
your
...
tests
...
match
...
our
...
...
.
...
Additional
...
information
...
on
...
how
...
to
...
best
...
migrate
...
JUnit3-style
...
tests
...
to
...
JUnit4
...
can
...
be
...
found
...
here.
Mockito
Mockito is a more recent mocking library. We'll not 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
Setting up for Magnolia testing
There are some handy classes available when creating tests for your Magnolia functionality. To get them working in your Maven project, add the following dependencies to your project descriptor.
Code Block | ||
---|---|---|
| ||
|http://wiki.magnolia-cms.com/display/DEV/Converting+JUnit3+tests+to+4-style]. h2. [Mockito|http://code.google.com/p/mockito/] Mockito is a more recent mocking library. We'll not 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 h2. Setting up for Magnolia testing There are some handy classes available when creating tests for your Magnolia functionality. To get them working in your Maven project, add the following dependencies to your project descriptor. {code:title=pom.xml} ... <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>1.8.5</version> <scope>test</scope> </dependency> <dependency> <groupId>info.magnolia</groupId> <artifactId>magnolia-core</artifactId> <version>${magnoliaVersion}</version> <type>test-jar</type> <scope>test</scope> </dependency> ... {code} h2. Magnolia Mocking overview 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, but usually we need to test objects that depend on other objects and there is where we use this 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. You can extend your test class from MgnlTestCase that will setup the basic environment for you and then use something |
Magnolia Mocking overview
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, but usually we need to test objects that depend on other objects and there is where we use this 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. You can extend your test class from MgnlTestCase that will setup the basic environment for you and then use something like:
Code Block |
---|
like: {code} HierarchyManager hm = MockUtil.createAndSetHierarchyManager(REPOSITORY, CONTENT); {code} |
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
- MgnlTestCase - Sets up a basic environment for the test, loads beans and modules properties and initializes a mock context as the local context.
- MockUtil - You can create mock objects and using createHierarchyManager you can build mock content based on a property file. The content can be force to be ordered and it allows you to create nodes, content, properties...
- MockContent - emulates a Content object used by MockUtil
- MockContext - emulates a context where you can set a mocked hierarchy manager
- RepositoryTestCase - Can be used to test on a real repository. It will initialize and delete it when finished.
- FactoryUtil - Class to allow various kinds of classes instantiations. Includes methods to convert content to beans.
Code Block |
---|
test * MgnlTestCase - Sets up a basic environment for the test, loads beans and modules properties and initializes a mock context as the local context. * MockUtil - You can create mock objects and using createHierarchyManager you can build mock content based on a property file. The content can be force to be ordered and it allows you to create nodes, content, properties... * MockContent - emulates a Content object used by MockUtil * MockContext - emulates a context where you can set a mocked hierarchy manager * RepositoryTestCase - Can be used to test on a real repository. It will initialize and delete it when finished. * FactoryUtil - Class to allow various kinds of classes instantiations. Includes methods to convert content to beans. {code} final SystemContext sysCtx = createStrictMock(SystemContext.class); sysCtx.setLocale(Locale.ENGLISH); FactoryUtil.setInstance(SystemContext.class, sysCtx); {code} |
What
...
this
...
example
...
does
...
is
...
to
...
use
...
the
...
EasyMock
...
method
...
createStrictMock
...
that
...
creates
...
an
...
instance
...
of
...
the
...
SystemContext
...
inteface
...
meaning
...
that
...
it
...
creates
...
a
...
mock
...
object
...
that
...
implements
...
this
...
interface
...
checking
...
the
...
order
...
of
...
method
...
calls.
...
It
...
sets
...
the
...
property
...
Locale
...
to
...
this
...
new
...
context
...
and
...
then
...
uses
...
the
...
FactoryUtil
...
class
...
to
...
register
...
the
...
new
...
instance
...
which
...
will
...
be
...
returned
...
by
...
getSingleton()
...
Magnolia Mock Objects
Content API Mocks
The customized mock objects that we provide to be able to setup an environment for Magnolia tests can be found in package info.magnolia.test.mock.
...
When
...
creating
...
a
...
mock
...
hierarchy
...
manager
...
you
...
can
...
either
...
initialize
...
it
...
from
...
a
...
properties
...
file:
Code Block | ||||
---|---|---|---|---|
| =
| |||
}main@type = mgnl:content main@uuid = 1 main/uuidLink@type = mgnl:contentNode main/uuidLink@uuid = 2 main/uuidLink.MetaData.mgnl\:template = someParagraphName main/uuidLink.MetaData.mgnl\:authorid = superuser main/uuidLink.MetaData.mgnl\:activatorid = superuser main/uuidLink.MetaData.mgnl\:title = myTitle main/uuidLink.link1 = 3 main/linkTarget@type = mgnl:content main/linkTarget@uuid = 3 main/linkTarget.prop1 = sub2value1 main/linkTarget.prop2 = sub2value2 main/linkTarget.prop3 = boolean:false main/content@type = mgnl:contentNode main/content@uuid = 4 main/content.value = Content Value {code} {code:title= |
Code Block | ||
---|---|---|
| ||
}HierarchyManager hm = MockUtil.createAndSetHierarchyManager(ContentRepository.USERS, getClass().getResourceAsStream("sample.properties")); {code} |
or
...
you
...
can
...
create
...
a
...
variable
...
with
...
the
...
data
...
or
...
pass
...
it
...
to
...
the
...
method
...
call
...
directly:
Code Block | |||
---|---|---|---|
|
| ||
}final String CONTENT = StringUtils.join(Arrays.asList( "main/content@type=mgnl:contentNode", "main/content@uuid=4", "main/content.value=Content Value" ), "\n"); HierarchyManager hm = MockUtil.createAndSetHierarchyManager(ContentRepository.USERS, CONTENT); {code} |
You
...
may
...
also
...
directly
...
instantiate
...
a
...
MockContent
...
and
...
then
...
add
...
the
...
child
...
Contents
...
and
...
or
...
NodeData's
...
as
...
required
Code Block | ||||
---|---|---|---|---|
| =
| |||
} MockContent page = new MockContent("page"); page.createContent("subpage", ItemType.CONTENT); page.setNodeData("stringProperty", "HelloWorld"); {code} h3. JCR Mocks Since Magnolia |
JCR Mocks
Since Magnolia 4.5
...
we
...
provide
...
the
...
package
...
info.magnolia.test.mock.jcr
...
containing
...
proper
...
mock's
...
for
...
javax.jcr.Node,
...
javax.jcr.Session
...
etc.
...
They're
...
extending
...
abstract
...
types
...
provided
...
in
...
...
.
...
The
...
types
...
of
...
the
...
Content
...
API
...
are
...
now
...
basically
...
just
...
wrapping
...
these
...
new
...
mocks.
...
If
...
required
...
you
...
can
...
always
...
create
...
a
...
MockContent
...
from
...
a
...
MockNode
...
or
...
a
...
MockHierarchyManager
...
from
...
a
...
MockSession.
...
With
...
the
...
help
...
of
...
info.magnolia.test.mock.jcr.SessionTestUtil
...
MockNodes
...
can
...
be
...
created
...
from
...
properties
...
files
Code Block | ||||
---|---|---|---|---|
| =
| |||
} MockSession session = SessionTestUtil.createSession("test", getClass().getResourceAsStream("sample.properties")); {code} |
as
...
well
...
as
...
from
...
String:
Code Block | ||||
---|---|---|---|---|
| =
| |||
} MockSession session = SessionTestUtil.createSession("testWorkspace", "/foo/bar.@type=mgnl:content", "/foo/bar/sub1.@uuid=1", "/foo/bar/subpath.property=testName"); {code} |
Of
...
course
...
there's
...
also
...
an
...
proper
...
API
...
for
...
it:
Code Block | ||||
---|---|---|---|---|
| =
| |||
} MockNode root = new MockNode(); root.addNode(MetaData.DEFAULT_META_NODE); root.setProperty("stringProperty", "HelloWorld"); {code} |