Multi module project contains Java test libraries to provider test and Mockito mock helpers.
- magkit-test-jcr - for JCR mocking
- magkit-test-servlet - for servlet container mocking
- magkit-test-cms - for Magnolia CMS mocking and testing
- magkit-test-server - for running JUnit tests within a Tomcat running our webapp
This repository contains some example best practices for open source repositories:
Issues are tracked at GitHub.
Any bug reports, improvement or feature pull requests are very welcome! Make sure your patches are well tested. Ideally create a topic branch for every separate change you make. For example:
- Fork the repo
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
The code is built by GitHub actions. You can browse available artifacts through Magnolia's Nexus
<dependency>
<artifactId>magkit-test-cms</artifactId>
<groupId>de.ibmix.magkit</groupId>
<version>1.0.0</version>
</dependency>
The project provides a consistent family of test utilities to build rich, internally consistent Mockito mocks for JCR, Servlet and Magnolia CMS environments. Each module follows the same core patterns:
- MockUtils classes (e.g.
NodeMockUtils
,SessionMockUtils
,ServletMockUtils
, Magnolia specificComponentsMockUtils
) expose static factory methodsmockXxx(...)
with optional varargs of stubbing operations. - StubbingOperation classes (e.g.
NodeStubbingOperation
,HttpServletRequestStubbingOperation
) encapsulate behavior changes. Chain them through varargs at creation time or apply later viaoperation.of(existingMock)
to keep tests DRY and readable. - Get-or-create & ThreadLocal context: Factories return an existing mock if already created in the current thread, ensuring hierarchical consistency (e.g. a mocked Node implies a Session, Workspace, Repository). ThreadLocal isolation supports parallel test execution.
- Deterministic defaults: Each mock ships with safe baseline behavior (no NPEs, minimal required relationships, sensible identifiers / types).
- Explicit cleanup: Call the appropriate cleanup between tests if state should not leak:
- JCR:
SessionMockUtils.cleanSession()
(equivalent toRepositoryMockUtils.cleanRepository()
). - Servlet: (if provided) context/session cleanup via dedicated utilities (see module README).
- Magnolia CMS:
ContextMockUtils.cleanContext()
/ component cleanup helpers.
- JCR:
Direct Mockito stubbing (e.g. when(node.getProperty("x"))...
) can desynchronize internal collections or related mocks. StubbingOperation implementations update all correlated aspects (lists, parent/child relations, session propagation, request ↔ session ↔ servlet context wiring). This preserves invariants your application code expects.
import static de.ibmix.magkit.test.jcr.NodeMockUtils.mockNode;
import static de.ibmix.magkit.test.jcr.NodeStubbingOperation.*; // e.g. stubProperty
import static de.ibmix.magkit.test.servlet.ServletMockUtils.mockHttpServletRequest;
import static de.ibmix.magkit.test.servlet.HttpServletRequestStubbingOperation.stubHeader;
import static de.ibmix.magkit.test.cms.context.ComponentsMockUtils.mockComponentInstance;
// 1. JCR: Create / fetch a hierarchical node context with properties
var article = mockNode("website", "/content/articles/2025-10", stubProperty("title", "Hello"));
// 2. Servlet: Prepare request with header + consistent session/context
var request = mockHttpServletRequest(stubHeader("Accept", "application/json"));
// 3. Magnolia: Register a component mock so downstream code retrieves it via Magnolia Components
var i18n = mockComponentInstance(info.magnolia.cms.i18n.I18nContentSupport.class);
// 4. Enrich later while keeping invariants
stubProperty("summary", "Short intro").of(article);
Module | Focus | Representative Factory | Cleanup |
---|---|---|---|
magkit-test-jcr | JCR Repository / Session / Node / Property | mockNode(path, stubbings...) / mockSession(ws, ...) |
SessionMockUtils.cleanSession() |
magkit-test-servlet | Servlet API (request, response, session, context) | mockHttpServletRequest(stubbings...) |
(Module handles base; see README) |
magkit-test-cms | Magnolia context, components, node types | mockComponentInstance(MyType.class) / mockPageNode(path, ...) |
ContextMockUtils.cleanContext() |
magkit-test-server | Embedded Tomcat + Magnolia for integration tests | JUnit5 @ExtendWith(MagnoliaTomcatExtension.class) |
Standard JUnit lifecycle |
- Prefer static imports of
*MockUtils
and*StubbingOperation
for clarity. - Keep each test self-contained: clean before (and optionally after) each method if order-independence matters.
- Avoid partial manual Mockito stubbing that bypasses provided operations—risk of inconsistent internal state.
- Layer only what you need: start with minimal mock + targeted stubbings to reduce cognitive overhead.
Each module README provides deeper examples:
If you miss a helper or stubbing operation, open an issue or PR with a focused, tested proposal.
All source files must include a Copyright and License header. The SPDX license header is preferred because it can be easily scanned.
If you would like to see the detailed LICENSE click here.
#
# Copyright 2023- IBM Inc. All rights reserved
# SPDX-License-Identifier: Apache2.0
#
Optionally, you may include a list of authors, though this is redundant with the built-in GitHub list of contributors.
- Author: Wolf Bubenik - [email protected]