You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2014/10/13 15:54:56 UTC
svn commit: r1631393 - in /sling: site/trunk/content/documentation/
site/trunk/content/documentation/development/
trunk/testing/jcr-mock/src/site/ trunk/testing/osgi-mock/src/site/
trunk/testing/sling-mock/src/site/
Author: sseifert
Date: Mon Oct 13 13:54:56 2014
New Revision: 1631393
URL: http://svn.apache.org/r1631393
Log:
SLING-4042 mock documentation
Added:
sling/site/trunk/content/documentation/development/jcr-mock.mdtext
sling/site/trunk/content/documentation/development/osgi-mock.mdtext
sling/site/trunk/content/documentation/development/resourceresolver-mock.mdtext
sling/site/trunk/content/documentation/development/sling-mock.mdtext
Removed:
sling/trunk/testing/jcr-mock/src/site/
sling/trunk/testing/osgi-mock/src/site/
sling/trunk/testing/sling-mock/src/site/
Modified:
sling/site/trunk/content/documentation/development.mdtext
Modified: sling/site/trunk/content/documentation/development.mdtext
URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development.mdtext?rev=1631393&r1=1631392&r2=1631393&view=diff
==============================================================================
--- sling/site/trunk/content/documentation/development.mdtext (original)
+++ sling/site/trunk/content/documentation/development.mdtext Mon Oct 13 13:54:56 2014
@@ -13,10 +13,17 @@ Look here for more information on develo
* [Client Request Logging]({{ refs.client-request-logging.path }})
* [Monitoring Requests]({{ refs.monitoring-requests.path }})
* [Repository Based Development]({{ refs.repository-based-development.path }})
-* [Sling Testing Tools]({{ refs.sling-testing-tools.path }})
* [Sling IDE Tooling]({{ refs.ide-tooling.path }})
+## Testing Sling-based Applications
+* [Sling Testing Tools]({{ refs.sling-testing-tools.path }})
+* [Resource Resolver Mock]({{ refs.resourceresolver-mock.path }})
+* [Sling Mock]({{ refs.sling-mock.path }})
+* [OSGi Mock]({{ refs.osgi-mock.path }})
+* [JCR Mock]({{ refs.jcr-mock.path }})
+
+
## Maven Stuff
Sling is using Apache Maven 3 as its build system. Over time we have created a number of Maven 3 plugins and gathered a whole range of knowledge about using Maven.
Added: sling/site/trunk/content/documentation/development/jcr-mock.mdtext
URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/jcr-mock.mdtext?rev=1631393&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/development/jcr-mock.mdtext (added)
+++ sling/site/trunk/content/documentation/development/jcr-mock.mdtext Mon Oct 13 13:54:56 2014
@@ -0,0 +1,54 @@
+Title: JCR Mock
+
+Mock implementation of selected JCR APIs for easier testing.
+
+
+## Maven Dependency
+
+```xml
+<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.jcr-mock</artifactId>
+</dependency>
+```
+
+See latest version on the [downloads page]({{ refs.downloads.path }}).
+
+
+## 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
+
+The following features are *not supported*:
+
+* Node types are supported in the API, but their definitions and constraints are not applied
+* Versioning not supported
+* Search 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:
+
+```java
+// 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 fill it with content.
Added: sling/site/trunk/content/documentation/development/osgi-mock.mdtext
URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/osgi-mock.mdtext?rev=1631393&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/development/osgi-mock.mdtext (added)
+++ sling/site/trunk/content/documentation/development/osgi-mock.mdtext Mon Oct 13 13:54:56 2014
@@ -0,0 +1,93 @@
+Title: OSGi Mock
+
+Mock implementation of selected OSGi APIs for easier testing.
+
+
+## Maven Dependency
+
+```xml
+<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+</dependency>
+```
+
+See latest version on the [downloads page]({{ refs.downloads.path }}).
+
+
+## Implemented mock features
+
+The mock implementation supports:
+
+* Instantiating OSGi `Bundle`, `BundleContext` and `ComponentContext` objects and navigate between them.
+* Read and write properties on them.
+* Register OSGi services and get references to service instances
+* Service and bundle listener implementation
+* When adding services to BundleContext OSGi metadata from `/OSGI-INF/<pid>.xml` is read (e.g. for service ranking property)
+* Mock implementation of `LogService` which logs to SLF4J in JUnit context
+
+The following features are *not supported*:
+
+* Activation and deactivation methods of services are not called automatically (but helper methods exist)
+* Dependency injection does not take place automatically (but helper methods exist)
+
+
+## Usage
+
+### Getting OSGi mock objects
+
+The factory class `MockOsgi` allows to instantiate the different mock implementations.
+
+Example:
+
+```java
+// get bundle context
+BundleContext bundleContext = MockOsgi.newBundleContext();
+
+// get component context
+Dictionary<String,Object> properties = new Hashtable<>();
+properties.put("prop1", "value1");
+BundleContext bundleContext = MockOsgi.newComponentContext(properties);
+```
+
+It is possible to simulate registering of OSGi services (backed by a simple hash map internally):
+
+```java
+// register service
+bundleContext.registerService(MyClass.class, myService, properties);
+
+// get service instance
+ServiceReference ref = bundleContext.getServiceReference(MyClass.class.getName());
+MyClass service = bundleContext.getService(ref);
+```
+
+### Activation and Dependency Injection
+
+It is possible to simulate OSGi service activation, deactivation and dependency injection and the mock implementation
+tries to to its best to execute all as expected for an OSGi environment.
+
+Example:
+
+```java
+// get bundle context
+BundleContext bundleContext = MockOsgi.newBundleContext();
+
+// create service instance manually
+MyService service = new MyService();
+
+// inject dependencies
+MockOsgi.injectServices(service, bundleContext);
+
+// activate service
+MockOsgi.activate(service, props);
+
+// operate with service...
+
+// deactivate service
+MockOsgi.deactivate(service);
+```
+
+Please note: The injectServices, activate and deactivate Methods can only work properly when the SCR XML metadata files
+are preset in the classpath at `/OSGI-INF`. They are generated automatically by the Maven SCR plugin, but might be
+missing if your clean and build the project within your IDE (e.g. Eclipse). In this case you have to compile the
+project again with maven and can run the tests - or use a Maven IDE Integration like m2eclipse.
Added: sling/site/trunk/content/documentation/development/resourceresolver-mock.mdtext
URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/resourceresolver-mock.mdtext?rev=1631393&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/development/resourceresolver-mock.mdtext (added)
+++ sling/site/trunk/content/documentation/development/resourceresolver-mock.mdtext Mon Oct 13 13:54:56 2014
@@ -0,0 +1,47 @@
+Title: Resource Resolver Mock
+
+Mock for the resource resolver / factory for easier testing.
+
+
+## Maven Dependency
+
+```xml
+<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
+</dependency>
+```
+
+See latest version on the [downloads page]({{ refs.downloads.path }}).
+
+
+## Implemented mock features
+
+The mock implementation supports:
+
+* All read and write operations of the Sling Resource API
+* Mimicks transactions using via commit()/revert() methods
+* OSGi events for adding/changing/removing resources
+* The implementation tries to be as close as possible to the behavior of the JCR resource implementation e.g. concerning date and binary handling
+
+
+The following features are *not supported*:
+
+* Authentication not supported ("login" always possible with null authentication info)
+* Querying with qeuryResources/findResources not supported (always returns empty result set)
+* Sling Mapping is not supported
+* Resolving resouce super types
+
+
+
+## Usage
+
+To create a mocked resource resolver:
+
+ #!java
+ MockResourceResolverFactory factory = new MockResourceResolverFactory();
+ ResourceResolver resolver = factory.getResourceResolver(null);
+
+With the resolver you can use all Sling Resource features including reading and writing data using the Sling API.
+
+You cannot do any operations that require the JCR API because no JCR is underlying and adapting to JCR objects will just return null.
Added: sling/site/trunk/content/documentation/development/sling-mock.mdtext
URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/sling-mock.mdtext?rev=1631393&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/development/sling-mock.mdtext (added)
+++ sling/site/trunk/content/documentation/development/sling-mock.mdtext Mon Oct 13 13:54:56 2014
@@ -0,0 +1,351 @@
+Title: Sling Mock
+
+Mock implementation of selected Sling APIs for easier testing.
+
+
+## Maven Dependency
+
+```xml
+<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+</dependency>
+```
+
+See latest version on the [downloads page]({{ refs.downloads.path }}).
+
+
+## Implemented mock features
+
+The mock implementation supports:
+
+* `ResourceResolver` implementation for reading and writing resource data using the Sling Resource API
+ * Backed by a [mocked][jcr-mock] or real Jackrabbit JCR implementation
+ * Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping
+ * Alternatively the non-JCR mock implementation provided by the
+ [Sling resourceresolver-mock implementation][resourceresolver-mock] can be used
+* `AdpaterManager` implementation for registering adapter factories and resolving adaptions
+ * The implementation is thread-safe so it can be used in parallel running unit tests
+* `SlingScriptHelper` implementation providing access to mocked request/response objects and supports getting
+ OSGi services from the [mocked OSGi][osgi-mock] environment.
+* Implementations of the servlet-related Sling API classes like `SlingHttpServletRequest` and `SlingHttpServletRequest`
+ * It is possible to set request data to simulate a certian Sling HTTP request
+* Additional services like `MockModelAdapterFactory` and `MimeTypeService`
+
+The following features are *not supported*:
+
+* It is not possible (nor intended) to really execute sling components/scripts and render their results.
+ * The goal is to test supporting classes in Sling context, not the sling components/scripts themselves
+
+
+### Additional features
+
+Additional features provided:
+
+* `ContentLoader` supports importing JSON data and binary data into the mock resource hierarchy to easily
+ prepare a test fixture consisting of a hierarchy of resources and properties.
+ * The same JSON format can be used that is provided by the Sling GET servlet for output
+* `ContentBuilder` makes it easier to create resources and properties as test fixture
+
+
+## Usage
+
+### Sling Context JUnit Rule
+
+The Sling mock context can be injected into a JUnit test using a custom JUnit rule named `SlingContext`.
+This rules takes care of all initialization and cleanup tasks required to make sure all unit tests can run
+independently (and in parallel, if required).
+
+Example:
+
+```java
+public class ExampleTest {
+
+ @Rule
+ public final SlingContext context = new SlingContext();
+
+ @Test
+ public void testSomething() {
+ Resource resource = context.resourceResolver().getResource("/content/sample/en");
+ // further testing
+ }
+
+}
+
+```
+
+It is possible to combine such a unit test with a `@RunWith` annotation e.g. for
+[Mockito JUnit Runner][mockito-testrunner].
+
+The `SlingContext` object provides access to mock implementations of:
+
+* OSGi Component Context
+* OSGi Bundle Context
+* Sling Resource Resolver
+* Sling Request
+* Sling Response
+* Sling Script Helper
+
+Additionally it supports:
+
+* Registering OSGi services
+* Registering adapter factories
+* Accessing Content Loader and Content Builder
+
+
+### Choosing Resource Resolver Mock Type
+
+The Sling mock context supports different resource resolver types. Example:
+
+```java
+public class ExampleTest {
+
+ @Rule
+ public final SlingContext context = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK);
+
+}
+
+```
+
+Different resource resolver mock types are supported with pros and cons, see next chapter for details.
+
+
+## Resource Resolver Types
+
+The Sling Mocks resource resolver implementation supports different "types" of adapters for the mocks.
+Depending on the type an underlying JCR repository is used or not, and the data ist stored in-memory or in a real
+repository.
+
+This pages lists all resource resolver types currently supported.
+
+### RESOURCERESOLVER_MOCK (default)
+
+* Simulates an In-Memory resource tree, does not provide adaptions to JCR API.
+* Based on the [Sling resourceresolver-mock implementation][resourceresolver-mock] implementation
+* You can use it to make sure the code you want to test does not contain references to JCR API.
+* Behaves slightly different from JCR resource mapping e.g. handling binary and date values.
+* This resource resolver type is very fast because data is stored in memory and no JCR mapping is applied.
+
+### JCR_MOCK
+
+* Based on the [JCR Mocks][jcr-mock] implementation
+* Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping
+* Is quite fast because data is stored only in-memory
+
+### JCR_JACKRABBIT
+
+* Uses a real JCR Jackrabbit implementation (not Oak) as provided by [sling/commons/testing][sling-comons-testing]
+* Full JCR/Sling features supported e.g. observations manager, transactions, versioning
+* Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping
+* Takes some seconds for startup on the first access
+* All node types that are used when reading/writing data have to be registered
+
+_Warnings/Remarks_
+
+* The repository is not cleared for each unit test, so make sure us use a unique node path for each unit test.
+* To import Sling content you have to fully register all node types required for the data
+* The [sling/commons/testing][sling-comons-testing] dependency introduces a lot of further dependencies from
+ jackrabbit and others, be careful that they do not conflict and are imported in the right order in your test project
+
+To use this type you have to declare an additional dependency in your test project:
+
+```xml
+<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.sling-mock-jackrabbit</artifactId>
+ <scope>test</scope>
+</dependency>
+```
+
+See latest version on the [downloads page]({{ refs.downloads.path }}).
+
+
+### Sling Resource Resolver
+
+Example:
+
+```java
+// get a resource resolver
+ResourceResolver resolver = MockSling.newResourceResolver();
+
+// get a resource resolver backed by a specific repository type
+ResourceResolver resolver = MockSling.newResourceResolver(ResourceResolverType.JCR_MOCK);
+```
+
+### Adapter Factories
+
+You can register your own or existing adapter factories to support adaptions e.g. for classes extending `SlingAdaptable`.
+
+Example:
+
+```java
+// register adapter factory
+BundleContext bundleContext = MockOsgi.newBundleContext();
+MockSling.setAdapterManagerBundleContext(bundleContext);
+bundleContext.registerService(myAdapterFactory);
+
+// test adaption
+MyClass object = resource.adaptTo(MyClass.class);
+
+// cleanup after unit test
+MockSling.clearAdapterManagerBundleContext();
+```
+
+Make sure you clean up the adapter manager bundle association after running the unit test otherwise it can
+interfere with the following tests. If you use the `SlingContext` Junit rule this is done automatically for you.
+
+
+### SlingScriptHelper
+
+Example:
+
+```java
+// get script helper
+SlingScriptHelper scriptHelper = MockSling.newSlingScriptHelper();
+
+// get request
+SlingHttpServletRequest request = scriptHelper.getRequest();
+
+// get service
+MyService object = scriptHelper.getService(MyService.class);
+```
+
+To support getting OSGi services you have to register them via the `BundleContext` interface of the
+[JCR Mocks][jcr-mock] before. You can use an alternative factory method for the `SlingScriptHelper` providing
+existing instances of request, response and bundle context.
+
+
+### SlingHttpServletRequest
+
+Example for preparing a sling request with custom request data:
+
+```java
+// prepare sling request
+ResourceResolver resourceResolver = MockSling.newResourceResolver();
+MockSlingHttpServletRequest request = new MockSlingHttpServletRequest(resourceResolver);
+
+// simulate query string
+request.setQueryString("param1=aaa¶m2=bbb");
+
+// alternative - set query parameters as map
+request.setParameterMap(ImmutableMap.<String,Object>builder()
+ .put("param1", "aaa")
+ .put("param2", "bbb")
+ .build());
+
+// set current resource
+request.setResource(resourceResolver.getResource("/content/sample"));
+
+// set sling request path info properties
+MockRequestPathInfo requestPathInfo = (MockRequestPathInfo)request.getRequestPathInfo();
+requestPathInfo.setSelectorString("selector1.selector2");
+requestPathInfo.setExtension("html");
+
+// set method
+request.setMethod(HttpConstants.METHOD_POST);
+
+// set attributes
+request.setAttribute("attr1", "value1");
+
+// set headers
+request.addHeader("header1", "value1");
+
+// set cookies
+request.addCookie(new Cookie("cookie1", "value1"));
+```
+
+### SlingHttpServletResponse
+
+Example for preparing a sling response which can collect the data that was written to it:
+
+```java
+// prepare sling response
+MockSlingHttpServletResponse response = new MockSlingHttpServletResponse();
+
+// execute your unit test code that writes to the response...
+
+// validate status code
+assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+
+// validate content type and content length
+assertEquals("text/plain;charset=UTF-8", response.getContentType());
+assertEquals(CharEncoding.UTF_8, response.getCharacterEncoding());
+assertEquals(55, response.getContentLength());
+
+// validate headers
+assertTrue(response.containsHeader("header1"));
+assertEquals("5", response.getHeader("header2"));
+
+// validate response body as string
+assertEquals(TEST_CONTENT, response.getOutputAsString());
+
+// validate response body as binary data
+assertArrayEquals(TEST_DATA, response.getOutput());
+```
+
+
+### Import resource data from JSON file in classpath
+
+With the `ContentLoader` it is possible to import structured resource and property data from a JSON file stored
+in the classpath beneath the unit tests. This data can be used as text fixture for unit tests.
+
+Example JSON data:
+
+```json
+{
+ "jcr:primaryType": "app:Page",
+ "jcr:content": {
+ "jcr:primaryType": "app:PageContent",
+ "jcr:title": "English",
+ "app:template": "/apps/sample/templates/homepage",
+ "sling:resourceType": "sample/components/homepage",
+ "jcr:createdBy": "admin",
+ "jcr:created": "Thu Aug 07 2014 16:32:59 GMT+0200",
+ "par": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "foundation/components/parsys",
+ "colctrl": {
+ "jcr:primaryType": "nt:unstructured",
+ "layout": "2;colctrl-lt0",
+ "sling:resourceType": "foundation/components/parsys/colctrl"
+ }
+ }
+ }
+}
+```
+
+Example code to import the JSON data:
+
+```java
+ResourceResolver resolver = MockSling.newResourceResolver();
+ContentLoader contentLoader = new ContentLoader(resolver);
+contentLoader.json("/sample-data.json", "/content/sample/en");
+```
+
+This codes creates a new resource at `/content/sample/en` (and - if not existent - the parent resources) and
+imports the JSON data to this node. It can be accessed using the Sling Resource or JCR API afterwards.
+
+
+### Import binary data from file in classpath
+
+With the `ContentLoader` it is possible to import a binary file stored in the classpath beneath the unit tests.
+The data is stored usig a nt:file/nt:resource or nt:resource node type.
+
+Example code to import a binary file:
+
+```java
+ResourceResolver resolver = MockSling.newResourceResolver();
+ContentLoader contentLoader = new ContentLoader(resolver);
+contentLoader.binaryFile("/sample-file.gif", "/content/binary/sample-file.gif");
+```
+
+This codes creates a new resource at `/content/binary/sample-file.gif` (and - if not existent - the parent
+resources) and imports the binary data to a jcr:content subnode.
+
+
+
+[osgi-mock]: {{ refs.osgi-mock.path }}
+[jcr-mock]: {{ refs.jcr-mock.path }}
+[resourceresolver-mock]: {{ refs.resourceresolver-mock.path }}
+[jcr-resource]: http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/resource
+[sling-comons-testing]: http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/testing