JCR Mocks

Mock implementation of selected JCR APIs for easier testing. It stores all data in-memory in a HashMap to ensure instantly creating and destroying of the JCR repository.

Maven Dependency

<dependency>
  <groupId>org.apache.sling</groupId>
  <artifactId>org.apache.sling.testing.jcr-mock</artifactId>
</dependency>

See latest version on the downloads page.

Implemented mock features

The mock implementation supports:

  • Reading and writing all data (primitive values, arrays, binary data) via the JCR API
  • Creating any number of nodes and properties (stored in-memory in a hash map)
  • Register namespaces
  • Queries are supported by setting expected results for a given query

The following features are not supported:

  • Node types are supported in the API, but their definitions and constraints are not applied
  • Versioning not supported
  • Transactions not supported
  • Observation events can be registered but are ignored
  • Access control always grants access
  • Exporting/Importing data via document and system views not supported
  • Workspace management methods not supported

Usage

Getting JCR mock objects

The factory class MockJcr allows to instantiate the different mock implementations.

Example:

// get session
Session session = MockJcr.newSession();

// get repository
Repository repository = MockJcr.newRepository();

The repository is empty and contains only the root node. You can use the JCR API to read or write content.

Mocking queries

If you want to test code that contains a JCR query you can simulate a query execution and set the result to return during setting up your unit test.

Example:

// prepare mocked search result
List<Node> resultNodes = ImmutableList.of(node1, node2, node3);

// return this result for all queries
MockJcr.setQueryResult(session, resultNodes);

// return this result for a specific query
MockJcr.setQueryResult(session, "your query statement", Query.JCR_SQL2, resultNodes);

Alternatively you can use the MockJcr.addQueryResultHandler method to pass a callback object that allows you to return a query result after inspecting the given query object.

Mocking node type management

Since Version 1.6.8

If you want to test code that interacts with node types you can simulate real node type definitions while setting up your unit test.

Example:

String[] cndResourcesToLoad = new String[] {
        "/org/apache/jackrabbit/oak/builtin_nodetypes.cnd",
        "/your/test/nodetypes.cnd"
};
for (String resourceName : cndResourcesToLoad) {
    URL cndUrl = getClass().getResource(resourceName);
    if (cndUrl == null) {
        fail("Failed to load CND nodetypes resource: " + resourceName);
    }
    try (Reader reader = new InputStreamReader(cndUrl.openStream())) {
        MockJcr.loadNodeTypeDefs(session, reader);
    }
}

Mocking access control manager

Since Version 1.6.8

If you want to test code that interacts with the access control manager you can set your own mock implementation while setting up your unit test.

Example:

AccessControlManager acm = Mockito.mock(AccessControlManager.class);
MockJcr.setAccessControlManager(jcrSession, acm);
- ( JCR Mocks )