This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-resourceresolver-mock.git


The following commit(s) were added to refs/heads/master by this push:
     new 67dc86e  SLING-11455 ResourceProvider implementation (#8)
67dc86e is described below

commit 67dc86e643b8b1d13ccff7bfe218e14cf7ca5837
Author: Stefan Seifert <[email protected]>
AuthorDate: Mon Aug 22 13:20:06 2022 +0200

    SLING-11455 ResourceProvider implementation (#8)
---
 pom.xml                                            |  16 +-
 .../resourceresolver/MockFindQueryResources.java   |  74 ++++++++++
 .../resourceresolver/MockPropertyResource.java     |  21 ++-
 .../MockQueryLanguageProvider.java                 | 105 +++++++++++++
 .../testing/resourceresolver/MockResource.java     |  22 ++-
 .../resourceresolver/MockResourceProvider.java     | 164 +++++++++++++++++++++
 .../resourceresolver/MockResourceResolver.java     |  12 ++
 .../testing/resourceresolver/MockValueMap.java     |  43 +++++-
 .../testing/resourceresolver/package-info.java     |   2 +-
 .../CreateDeleteResourceResolverTest.java          |   9 +-
 .../resourceresolver/FindQueryResourcesTest.java   |  51 ++++---
 .../resourceresolver/IsResourceTypeTest.java       |   8 +-
 .../resourceresolver/NtFileResourceTest.java       |   6 +-
 .../resourceresolver/RootResourceTypeTest.java     |   6 +-
 .../SlingCrudResourceResolverTest.java             |  52 ++++++-
 .../testing/resourceresolver/ValueMapTest.java     |   6 +-
 ...eleteResourceResolverResourceProviderTest.java} |  38 ++---
 ...indQueryResourcesTestResourceProviderTest.java} |  38 ++---
 .../IsResourceTypeTestResourceProviderTest.java}   |  38 ++---
 .../provider/MockResourceProviderTest.java         |  71 +++++++++
 .../NtFileResourceTestResourceProviderTest.java}   |  38 ++---
 .../RootResourceTypeTestResourceProviderTest.java} |  38 ++---
 ...dResourceResolverTestResourceProviderTest.java} |  38 ++---
 .../ValueMapTestResourceProviderTest.java}         |  38 ++---
 24 files changed, 722 insertions(+), 212 deletions(-)

diff --git a/pom.xml b/pom.xml
index e666230..67b28c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
-    <version>1.3.1-SNAPSHOT</version>
+    <version>1.4.0-SNAPSHOT</version>
 
     <name>Apache Sling Testing Resource Resolver Mock</name>
     <description>
@@ -108,6 +108,18 @@
         </dependency>
 
         <!-- testing -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
+            <version>3.3.2</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.sling</groupId>
+                    
<artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -122,7 +134,7 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>4.5.1</version>
+            <version>4.7.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockFindQueryResources.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockFindQueryResources.java
new file mode 100644
index 0000000..3f55f87
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockFindQueryResources.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.resourceresolver;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Allows to provide mocked search result for queries via {@link 
ResourceResolver}.
+ * This works if {@link MockResourceResolver} is used directly or indirectly 
via {@link MockResourceProvider}.
+ */
+public final class MockFindQueryResources {
+
+    private MockFindQueryResources() {
+        // static methods only
+    }
+
+    /**
+     * Adds a handler that can provide a mocked find resources result. You can 
add multiple handlers which are called
+     * in the order they were added when calling {@link 
ResourceResolver#findResources(String, String)}.
+     * The result of the first handler that returns a non-null result is used.
+     * If no handler delivers a result, an empty result is returned.
+     * @param resourceResolver Resource resolver
+     * @param handler Handler
+     * @throws IllegalStateException If the given resource resolver is not 
based on resourceresolver-mock
+     */
+    public static void addFindResourceHandler(@NotNull ResourceResolver 
resourceResolver, @NotNull MockFindResourcesHandler handler) {
+        
toMockResourceResolver(resourceResolver).addFindResourceHandlerInternal(handler);
+    }
+
+    /**
+     * Adds a handler that can provide a mocked query resources result. You 
can add multiple handlers which are called
+     * in the order they were added when calling {@link 
ResourceResolver#queryResources(String, String)}.
+     * The result of the first handler that returns a non-null result is used.
+     * If no handler delivers a result, an empty result is returned.
+     * @param resourceResolver Resource resolver
+     * @param handler Handler
+     * @throws IllegalStateException If the given resource resolver is not 
based on resourceresolver-mock
+     */
+    public static void addQueryResourceHandler(@NotNull ResourceResolver 
resourceResolver, @NotNull MockQueryResourceHandler handler) {
+        
toMockResourceResolver(resourceResolver).addQueryResourceHandlerInternal(handler);
+    }
+
+    private static @NotNull MockResourceResolver 
toMockResourceResolver(@NotNull ResourceResolver resourceResolver) {
+        MockResourceResolver mockResourceResolver = null;
+        if (resourceResolver instanceof MockResourceResolver) {
+            mockResourceResolver = (MockResourceResolver)resourceResolver;
+        }
+        else {
+            mockResourceResolver = 
resourceResolver.adaptTo(MockResourceResolver.class);
+        }
+        if (mockResourceResolver == null) {
+            throw new IllegalStateException("The given resource resolver is 
not based on resourceresolver-mock.");
+        }
+        return mockResourceResolver;
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
index 011b5f5..82bba13 100644
--- 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
@@ -19,6 +19,7 @@
 package org.apache.sling.testing.resourceresolver;
 
 import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
@@ -34,7 +35,7 @@ class MockPropertyResource extends AbstractResource {
     private final ValueMap props;
     private final String key;
     private final ResourceResolver resolver;
-    private final ResourceMetadata rm = new ResourceMetadata();
+    private final ResourceMetadata rm;
 
     public MockPropertyResource(final String path,
             final ValueMap props,
@@ -42,6 +43,15 @@ class MockPropertyResource extends AbstractResource {
         this.path = path;
         this.props = props;
         this.key = ResourceUtil.getName(path);
+        this.rm = new ResourceMetadata();
+        this.resolver = resolver;
+    }
+
+    private MockPropertyResource(String path, ValueMap props, String key, 
ResourceMetadata rm, ResourceResolver resolver) {
+        this.path = path;
+        this.props = props;
+        this.key = key;
+        this.rm = rm;
         this.resolver = resolver;
     }
 
@@ -82,4 +92,13 @@ class MockPropertyResource extends AbstractResource {
         return super.adaptTo(type);
     }
 
+    /**
+     * Creates a new instance for this mock resource with referencing the 
given resoruce resolver (instead of the initial MockResourceResolver).
+     * @param resourceResolver Resource resolver
+     * @return Same resource with different resource resolver
+     */
+    Resource forResourceProvider(ResourceResolver resourceResolver) {
+        return new MockPropertyResource(this.path, this.props, this.key, 
this.rm, resourceResolver);
+    }
+
 }
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockQueryLanguageProvider.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockQueryLanguageProvider.java
new file mode 100644
index 0000000..baad67e
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockQueryLanguageProvider.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.resourceresolver;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.StreamSupport;
+
+import javax.jcr.query.Query;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceWrapper;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.jetbrains.annotations.NotNull;
+
+class MockQueryLanguageProvider implements QueryLanguageProvider<Void> {
+
+    private final MockResourceResolver mockResourceResolver;
+
+    @SuppressWarnings("deprecation")
+    private static final String[] SUPPORTED_LANGUAGES = {
+            Query.XPATH,
+            Query.SQL,
+            Query.JCR_SQL2,
+            Query.JCR_SQL2
+    };
+
+    MockQueryLanguageProvider(MockResourceResolver mockResourceResolver) {
+        this.mockResourceResolver = mockResourceResolver;
+    }
+
+    @Override
+    public String[] getSupportedLanguages(@NotNull ResolveContext<Void> ctx) {
+        return SUPPORTED_LANGUAGES;
+    }
+
+    @Override
+    public Iterator<Resource> findResources(@NotNull ResolveContext<Void> ctx, 
String query, String language) {
+        return 
unlockResourceMetadata(mockResourceResolver.findResources(query, language));
+    }
+
+    @Override
+    public Iterator<ValueMap> queryResources(@NotNull ResolveContext<Void> 
ctx, String query, String language) {
+        Iterator<Map<String,Object>> result = 
mockResourceResolver.queryResources(query, language);
+        return 
StreamSupport.stream(Spliterators.spliteratorUnknownSize(result, 
Spliterator.ORDERED), false)
+                .map(MockQueryLanguageProvider::toValueMap)
+                .iterator();
+    }
+
+    private static ValueMap toValueMap(Map<String,Object> item) {
+        if (item instanceof ValueMap) {
+            return (ValueMap)item;
+        }
+        else {
+            return new ValueMapDecorator(item);
+        }
+    }
+
+    private static Iterator<Resource> 
unlockResourceMetadata(Iterator<Resource> iterator) {
+        return 
StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 
Spliterator.ORDERED), false)
+                .map(MockQueryLanguageProvider::unlockResourceMetadata)
+                .iterator();
+    }
+
+    /**
+     * ResourceResolver locks resources returned by ResourceProvider. If those 
resources are used to mock up
+     * the query result, it fails because during processing the query result 
the resolution path in the query metdata
+     * is set again. So we need to wrap the resources and unlock the resource 
metadata here.
+     * @param resource Resource
+     * @return Wrapped resource with unlocked metadata
+     */
+    private static Resource unlockResourceMetadata(Resource resource) {
+        ResourceMetadata rm = new ResourceMetadata();
+        rm.putAll(resource.getResourceMetadata());
+        return new ResourceWrapper(resource) {
+            @Override
+            public ResourceMetadata getResourceMetadata() {
+                return rm;
+            }
+        };
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
index 6bda1bd..89d75c8 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
@@ -36,7 +36,7 @@ public class MockResource extends AbstractResource {
 
     private final ValueMap props;
 
-    private final ResourceMetadata rm = new ResourceMetadata();
+    private final ResourceMetadata rm;
 
     private final ResourceResolver resolver;
 
@@ -52,7 +52,8 @@ public class MockResource extends AbstractResource {
             final ResourceResolver resolver) {
         this.resolver = resolver;
         this.path = path;
-        rm.setResolutionPath(path);
+        this.rm = new ResourceMetadata();
+        this.rm.setResolutionPath(path);
         if (props instanceof MockValueMap) {
             this.props = (MockValueMap)props;
         }
@@ -64,6 +65,13 @@ public class MockResource extends AbstractResource {
         }
     }
 
+    private MockResource(String path, ValueMap props, ResourceMetadata rm, 
ResourceResolver resolver) {
+        this.path = path;
+        this.props = props;
+        this.rm = rm;
+        this.resolver = resolver;
+    }
+
     @Override
     public @NotNull String getPath() {
         return this.path;
@@ -105,7 +113,6 @@ public class MockResource extends AbstractResource {
             return (AdapterType)new ReadonlyValueMapDecorator(this.props);
         }
         else if ( type == ModifiableValueMap.class ) {
-            ((MockResourceResolver)this.resolver).addChanged(this.path, 
this.props);
             return (AdapterType)this.props;
         }
         else if ( type == InputStream.class ) {
@@ -145,4 +152,13 @@ public class MockResource extends AbstractResource {
         return "MockResource [path=" + path + ", props=" + props + "]";
     }
 
+    /**
+     * Creates a new instance for this mock resource with referencing the 
given resoruce resolver (instead of the initial MockResourceResolver).
+     * @param resourceResolver Resource resolver
+     * @return Same resource with different resource resolver
+     */
+    Resource forResourceProvider(ResourceResolver resourceResolver) {
+        return new MockResource(this.path, this.props, this.rm, 
resourceResolver);
+    }
+
 }
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceProvider.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceProvider.java
new file mode 100644
index 0000000..6cfc41b
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceProvider.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.resourceresolver;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.StreamSupport;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.event.EventAdmin;
+
+/**
+ * This is a wrapper around {@link MockResourceResolver} to act as resource 
provider.
+ * All resources returned by this provider return the resolver from the 
resolve context instead of the {@link MockResourceResolver}.
+ */
+@Component(service = ResourceProvider.class, property = {
+        ResourceProvider.PROPERTY_NAME + "=MockResourceProvider",
+        ResourceProvider.PROPERTY_ROOT + "=/",
+        ResourceProvider.PROPERTY_MODIFIABLE + ":Boolean=true",
+        ResourceProvider.PROPERTY_ADAPTABLE + ":Boolean=true",
+        // although we do not really support authentication, it's required for 
a modifiable resource provider
+        ResourceProvider.PROPERTY_AUTHENTICATE + "=" + 
ResourceProvider.AUTHENTICATE_REQUIRED
+})
+public final class MockResourceProvider extends ResourceProvider<Void> {
+
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL)
+    private EventAdmin eventAdmin;
+
+    private MockResourceResolver mockResourceResolver;
+    private MockQueryLanguageProvider mockQueryLanguageProvider;
+
+    @Activate
+    private void activate() {
+        MockResourceResolverFactoryOptions options = new 
MockResourceResolverFactoryOptions();
+        options.setMangleNamespacePrefixes(true);
+        options.setEventAdmin(eventAdmin);
+        ResourceResolverFactory resourceResolverFactory = new 
MockResourceResolverFactory(options);
+        try {
+            this.mockResourceResolver = 
(MockResourceResolver)resourceResolverFactory.getResourceResolver(null);
+        }
+        catch (LoginException ex) {
+            throw new RuntimeException(ex);
+        }
+        this.mockQueryLanguageProvider = new 
MockQueryLanguageProvider(mockResourceResolver);
+    }
+
+    @Override
+    public @Nullable Resource getResource(@NotNull ResolveContext<Void> ctx,
+            @NotNull String path, @NotNull ResourceContext resourceContext,
+            @Nullable Resource parent) {
+        Resource resource = mockResourceResolver.getResource(path);
+        if (resource != null) {
+            return attachResource(ctx, resource);
+        }
+        else {
+            return null;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("null")
+    public @Nullable Iterator<Resource> listChildren(
+            @NotNull ResolveContext<Void> ctx, @NotNull Resource parent) {
+        Iterator<Resource> children = 
mockResourceResolver.listChildren(parent);
+        return 
StreamSupport.stream(Spliterators.spliteratorUnknownSize(children, 
Spliterator.ORDERED), false)
+                .map(resource -> attachResource(ctx, resource))
+                .iterator();
+    }
+
+    @Override
+    public @NotNull Resource create(@NotNull ResolveContext<Void> ctx, String 
path,
+            Map<String, Object> properties) throws PersistenceException {
+        String parentPath = ResourceUtil.getParent(path);
+        String name = ResourceUtil.getName(path);
+        if (parentPath == null) {
+            throw new PersistenceException("Invalid path: " + path);
+        }
+        Resource parent = mockResourceResolver.getResource(parentPath);
+        if (parent == null) {
+            throw new PersistenceException("Parent does not exist: " + 
parentPath);
+        }
+        Resource newResource = mockResourceResolver.create(parent, name, 
properties);
+        return attachResource(ctx, newResource);
+    }
+
+    @Override
+    public void delete(@NotNull ResolveContext<Void> ctx, @NotNull Resource 
resource) throws PersistenceException {
+        mockResourceResolver.delete(resource);
+    }
+
+    @Override
+    public void revert(@NotNull ResolveContext<Void> ctx) {
+        mockResourceResolver.revert();
+    }
+
+    @Override
+    public void commit(@NotNull ResolveContext<Void> ctx) throws 
PersistenceException {
+        mockResourceResolver.commit();
+    }
+
+    @Override
+    public boolean hasChanges(@NotNull ResolveContext<Void> ctx) {
+        return mockResourceResolver.hasChanges();
+    }
+
+    @Override
+    public @Nullable QueryLanguageProvider<Void> getQueryLanguageProvider() {
+        return mockQueryLanguageProvider;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public @Nullable <AdapterType> AdapterType adaptTo(@NotNull 
ResolveContext<Void> ctx, @NotNull Class<AdapterType> type) {
+        if (type == MockResourceResolver.class) {
+            return (AdapterType)mockResourceResolver;
+        }
+        return super.adaptTo(ctx, type);
+    }
+
+    private @NotNull Resource attachResource(@NotNull ResolveContext<Void> 
ctx, @NotNull Resource resource) {
+        if (resource instanceof MockResource) {
+            return 
((MockResource)resource).forResourceProvider(ctx.getResourceResolver());
+        }
+        else if (resource instanceof MockPropertyResource) {
+            return 
((MockPropertyResource)resource).forResourceProvider(ctx.getResourceResolver());
+        }
+        else {
+            return resource;
+        }
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
index 8cb5d1d..a96b897 100644
--- 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
@@ -493,8 +493,14 @@ public class MockResourceResolver extends SlingAdaptable 
implements ResourceReso
      * The result of the first handler that returns a non-null result is used.
      * If no handler delivers a result, an empty result is returned.
      * @param handler Handler
+     * @deprecated Please use {@link 
MockFindQueryResources#addFindResourceHandler(ResourceResolver, 
MockFindResourcesHandler)}
      */
+    @Deprecated
     public void addFindResourceHandler(@NotNull MockFindResourcesHandler 
handler) {
+        addFindResourceHandlerInternal(handler);
+    }
+
+    void addFindResourceHandlerInternal(@NotNull MockFindResourcesHandler 
handler) {
         findResourcesHandlers.add(handler);
     }
 
@@ -514,8 +520,14 @@ public class MockResourceResolver extends SlingAdaptable 
implements ResourceReso
      * The result of the first handler that returns a non-null result is used.
      * If no handler delivers a result, an empty result is returned.
      * @param handler Handler
+     * @deprecated Please use {@link 
MockFindQueryResources#addQueryResourceHandler(ResourceResolver, 
MockFindResourcesHandler)}
      */
+    @Deprecated
     public void addQueryResourceHandler(@NotNull MockQueryResourceHandler 
handler) {
+        addQueryResourceHandlerInternal(handler);
+    }
+
+    void addQueryResourceHandlerInternal(@NotNull MockQueryResourceHandler 
handler) {
         queryResourcesHandlers.add(handler);
     }
 
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java
index b629315..5aa4b67 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import org.apache.commons.io.IOUtils;
 import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.wrappers.DeepReadModifiableValueMapDecorator;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 
@@ -42,12 +43,27 @@ import org.apache.sling.api.wrappers.ValueMapDecorator;
  */
 public class MockValueMap extends DeepReadModifiableValueMapDecorator 
implements ModifiableValueMap {
 
+    private final Resource resource;
+    private final MockResourceResolver mockResourceResolver;
+
     public MockValueMap(Resource resource) {
-        this(resource, new HashMap<String, Object>());
+        this(resource, new HashMap<>());
     }
 
     public MockValueMap(Resource resource, Map<String,Object> map) {
         super(resource, new ValueMapDecorator(convertForWriteAll(map)));
+        this.resource = resource;
+        this.mockResourceResolver = getMockResourceResolver(resource);
+    }
+
+    private static MockResourceResolver getMockResourceResolver(Resource 
resource) {
+        ResourceResolver resolver = resource.getResourceResolver();
+        if (resolver instanceof MockResourceResolver) {
+            return (MockResourceResolver)resolver;
+        }
+        else {
+            return null;
+        }
     }
 
     @SuppressWarnings({ "unchecked", "null", "unused" })
@@ -72,13 +88,27 @@ public class MockValueMap extends 
DeepReadModifiableValueMapDecorator implements
 
     @Override
     public Object put(String key, Object value) {
+        markResourceAsChanged();
         return super.put(key, convertForWrite(value));
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public void putAll(Map<? extends String, ?> map) {
-        super.putAll((Map<? extends String, ?>)convertForWriteAll((Map<String, 
Object>)map));
+        markResourceAsChanged();
+        super.putAll(convertForWriteAll((Map<String, Object>)map));
+    }
+
+    @Override
+    public Object remove(Object key) {
+        markResourceAsChanged();
+        return super.remove(key);
+    }
+
+    @Override
+    public void clear() {
+        markResourceAsChanged();
+        super.clear();
     }
 
     private static Object convertForWrite(Object value) {
@@ -109,4 +139,13 @@ public class MockValueMap extends 
DeepReadModifiableValueMapDecorator implements
         return newMap;
     }
 
+    /**
+     * Put access to the value map - mark the resource as changed.
+     */
+    private void markResourceAsChanged() {
+        if (this.mockResourceResolver != null) {
+            this.mockResourceResolver.addChanged(resource.getPath(), this);
+        }
+    }
+
 }
diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/package-info.java 
b/src/main/java/org/apache/sling/testing/resourceresolver/package-info.java
index e5b6cf9..0a16cc8 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/package-info.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Apache Sling Testing Resource Resolver Mock
  */
[email protected]("2.2.1")
[email protected]("2.3.0")
 package org.apache.sling.testing.resourceresolver;
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/CreateDeleteResourceResolverTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/CreateDeleteResourceResolverTest.java
index 67a3b18..6ac6476 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/CreateDeleteResourceResolverTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/CreateDeleteResourceResolverTest.java
@@ -21,7 +21,6 @@ package org.apache.sling.testing.resourceresolver;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
-import java.io.IOException;
 import java.util.Map;
 
 import org.apache.sling.api.resource.LoginException;
@@ -50,12 +49,16 @@ public class CreateDeleteResourceResolverTest {
 
     @Before
     @SuppressWarnings("null")
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+    public final void setUp() throws Exception {
+        resourceResolver = createResourceResolver();
         Resource root = resourceResolver.getResource("/");
         testRoot = resourceResolver.create(root, "test", ValueMap.EMPTY);
     }
 
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
     @Test
     public void testCreateDeleteCreate() throws PersistenceException {
         // create new node without commit
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/FindQueryResourcesTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/FindQueryResourcesTest.java
index 53af208..de0397d 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/FindQueryResourcesTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/FindQueryResourcesTest.java
@@ -18,18 +18,23 @@
  */
 package org.apache.sling.testing.resourceresolver;
 
+import static javax.jcr.query.Query.JCR_SQL2;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
-import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -46,8 +51,8 @@ public class FindQueryResourcesTest {
     private Resource resource2;
 
     @Before
-    public void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+    public void setUp() throws Exception {
+        resourceResolver = createResourceResolver();
 
         MockHelper.create(resourceResolver)
             .resource("/resource1").p("prop1", "value1")
@@ -57,60 +62,72 @@ public class FindQueryResourcesTest {
         resource2 = resourceResolver.getResource("/resource2");
     }
 
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
     @Test
     public void testFindResourcesNoHandler() {
-        Iterator<Resource> result = 
resourceResolver.findResources("any-query", "any-language");
+        Iterator<Resource> result = 
resourceResolver.findResources("any-query", JCR_SQL2);
         assertFalse(result.hasNext());
     }
 
     @Test
     public void testFindResourcesSingleHandler() {
         List<Resource> expected = ImmutableList.of(resource1, resource2);
-        
((MockResourceResolver)resourceResolver).addFindResourceHandler((query, 
language) -> expected.iterator());
+        MockFindQueryResources.addFindResourceHandler(resourceResolver, 
(query, language) -> expected.iterator());
 
-        assertEquals(expected, 
ImmutableList.copyOf(resourceResolver.findResources("any-query", 
"any-language")));
+        assertResources(expected, resourceResolver.findResources("any-query", 
JCR_SQL2));
     }
 
     @Test
     public void testFindResourcesMultipleHandlers() {
         List<Resource> expected1 = ImmutableList.of(resource1);
-        
((MockResourceResolver)resourceResolver).addFindResourceHandler((query, 
language) ->
+        MockFindQueryResources.addFindResourceHandler(resourceResolver, 
(query, language) ->
             StringUtils.equals(query, "q1") ? expected1.iterator() : null);
 
         List<Resource> expected2 = ImmutableList.of(resource2);
-        
((MockResourceResolver)resourceResolver).addFindResourceHandler((query, 
language) ->
+        MockFindQueryResources.addFindResourceHandler(resourceResolver, 
(query, language) ->
             StringUtils.equals(query, "q2") ? expected2.iterator() : null);
 
-        assertEquals(expected1, 
ImmutableList.copyOf(resourceResolver.findResources("q1", "any-language")));
-        assertEquals(expected2, 
ImmutableList.copyOf(resourceResolver.findResources("q2", "any-language")));
+        assertResources(expected1, resourceResolver.findResources("q1", 
JCR_SQL2));
+        assertResources(expected2, resourceResolver.findResources("q2", 
JCR_SQL2));
     }
 
     @Test
     public void testQueryResourcesNoHandler() {
-        Iterator<Map<String,Object>> result = 
resourceResolver.queryResources("any-query", "any-language");
+        Iterator<Map<String,Object>> result = 
resourceResolver.queryResources("any-query", JCR_SQL2);
         assertFalse(result.hasNext());
     }
 
     @Test
     public void testQueryResourcesSingleHandler() {
         List<Map<String,Object>> expected = 
ImmutableList.of(resource1.getValueMap(), resource2.getValueMap());
-        
((MockResourceResolver)resourceResolver).addQueryResourceHandler((query, 
language) -> expected.iterator());
+        MockFindQueryResources.addQueryResourceHandler(resourceResolver, 
(query, language) -> expected.iterator());
 
-        assertEquals(expected, 
ImmutableList.copyOf(resourceResolver.queryResources("any-query", 
"any-language")));
+        assertEquals(expected, 
ImmutableList.copyOf(resourceResolver.queryResources("any-query", JCR_SQL2)));
     }
 
     @Test
     public void testQueryResourcesMultipleHandlers() {
         List<Map<String,Object>> expected1 = 
ImmutableList.of(resource1.getValueMap());
-        
((MockResourceResolver)resourceResolver).addQueryResourceHandler((query, 
language) ->
+        MockFindQueryResources.addQueryResourceHandler(resourceResolver, 
(query, language) ->
             StringUtils.equals(query, "q1") ? expected1.iterator() : null);
 
         List<Map<String,Object>> expected2 = 
ImmutableList.of(resource2.getValueMap());
-        
((MockResourceResolver)resourceResolver).addQueryResourceHandler((query, 
language) ->
+        MockFindQueryResources.addQueryResourceHandler(resourceResolver, 
(query, language) ->
             StringUtils.equals(query, "q2") ? expected2.iterator() : null);
 
-        assertEquals(expected1, 
ImmutableList.copyOf(resourceResolver.queryResources("q1", "any-language")));
-        assertEquals(expected2, 
ImmutableList.copyOf(resourceResolver.queryResources("q2", "any-language")));
+        assertEquals(expected1, 
ImmutableList.copyOf(resourceResolver.queryResources("q1", JCR_SQL2)));
+        assertEquals(expected2, 
ImmutableList.copyOf(resourceResolver.queryResources("q2", JCR_SQL2)));
+    }
+
+    private void assertResources(List<Resource> expected, Iterator<Resource> 
actual) {
+        Map<String,ValueMap> expectedData = expected.stream()
+                .collect(Collectors.toMap(Resource::getPath, 
Resource::getValueMap));
+        Map<String,ValueMap> actualData = 
StreamSupport.stream(Spliterators.spliteratorUnknownSize(actual, 
Spliterator.ORDERED), false)
+                .collect(Collectors.toMap(Resource::getPath, 
Resource::getValueMap));
+        assertEquals(expectedData, actualData);
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/IsResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/IsResourceTypeTest.java
index 44e26d7..2e19741 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/IsResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/IsResourceTypeTest.java
@@ -39,8 +39,12 @@ public class IsResourceTypeTest {
     private ResourceResolver resolver;
 
     @Before
-    public final void setUp() throws LoginException {
-        resolver = new MockResourceResolverFactory().getResourceResolver(null);
+    public void setUp() throws Exception {
+        resolver = createResourceResolver();
+    }
+
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
     }
 
     @Test
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/NtFileResourceTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/NtFileResourceTest.java
index f61b336..7a8c236 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/NtFileResourceTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/NtFileResourceTest.java
@@ -54,11 +54,15 @@ public class NtFileResourceTest {
 
     @Before
     public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+        resourceResolver = createResourceResolver();
         Resource root = resourceResolver.getResource("/");
         testRoot = resourceResolver.create(root, "test", ValueMap.EMPTY);
     }
 
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
     @Test
     public void testNtFile() throws IOException {
         Resource file = resourceResolver.create(testRoot, "ntFile", 
ImmutableMap.<String, Object>builder()
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
index 8a11945..c7f7345 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
@@ -33,7 +33,11 @@ public class RootResourceTypeTest {
 
     @Before
     public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+        resourceResolver = createResourceResolver();
+    }
+
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
     }
 
     @Test
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
index 16bf7c0..9ab3de1 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
@@ -74,7 +74,7 @@ public class SlingCrudResourceResolverTest {
 
     @Before
     public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+        resourceResolver = createResourceResolver();
 
         Resource root = resourceResolver.getResource("/");
         testRoot = resourceResolver.create(root, "test", ValueMap.EMPTY);
@@ -102,6 +102,10 @@ public class SlingCrudResourceResolverTest {
         resourceResolver.commit();
     }
 
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
     @Test
     public void testSimpleProperties() throws IOException {
         Resource resource1 = resourceResolver.getResource(testRoot.getPath() + 
"/node1");
@@ -293,7 +297,7 @@ public class SlingCrudResourceResolverTest {
 
     @Test
     public void testGetParentResourceType() throws PersistenceException {
-        Resource r1 = resourceResolver.create(testRoot, "resource1", 
ImmutableMap.<String, Object>of());
+        Resource r1 = resourceResolver.create(testRoot, "resource1", 
ValueMap.EMPTY);
         Resource r2 = resourceResolver.create(testRoot, "resource2", 
ImmutableMap.<String, Object>of(
                 "sling:resourceSuperType", testRoot.getPath() + "/resource1"));
         Resource r3 = resourceResolver.create(testRoot, "resource3", 
ImmutableMap.<String, Object>of(
@@ -317,7 +321,49 @@ public class SlingCrudResourceResolverTest {
 
     @Test
     public void testResourceWithoutResourceType() throws PersistenceException {
-        Resource noResourceType = resourceResolver.create(testRoot, 
"/noResourceType", ImmutableMap.<String, Object>of());
+        Resource noResourceType = resourceResolver.create(testRoot, 
"noResourceType", ValueMap.EMPTY);
         assertNotNull(noResourceType.getResourceType());
     }
+
+    @Test
+    public void testHasChanges_CreateResource() throws PersistenceException {
+        assertFalse(resourceResolver.hasChanges());
+        resourceResolver.create(testRoot, "res1", ValueMap.EMPTY);
+        assertTrue(resourceResolver.hasChanges());
+        resourceResolver.commit();
+        assertFalse(resourceResolver.hasChanges());
+    }
+
+    @Test
+    public void testHasChanges_SetProperties() throws PersistenceException {
+        assertFalse(resourceResolver.hasChanges());
+        Resource resource1 = resourceResolver.getResource(testRoot.getPath() + 
"/node1");
+        ModifiableValueMap props = resource1.adaptTo(ModifiableValueMap.class);
+        props.put("newProp", "value1");
+        assertTrue(resourceResolver.hasChanges());
+        resourceResolver.commit();
+        assertFalse(resourceResolver.hasChanges());
+    }
+
+    @Test
+    public void testHasChanges_RemoveProperty() throws PersistenceException {
+        assertFalse(resourceResolver.hasChanges());
+        Resource resource1 = resourceResolver.getResource(testRoot.getPath() + 
"/node1");
+        ModifiableValueMap props = resource1.adaptTo(ModifiableValueMap.class);
+        props.remove("stringProp");
+        assertTrue(resourceResolver.hasChanges());
+        resourceResolver.commit();
+        assertFalse(resourceResolver.hasChanges());
+    }
+
+    @Test
+    public void testHasChanges_DeleteResource() throws PersistenceException {
+        assertFalse(resourceResolver.hasChanges());
+        Resource resource1 = resourceResolver.getResource(testRoot.getPath() + 
"/node1");
+        resourceResolver.delete(resource1);
+        assertTrue(resourceResolver.hasChanges());
+        resourceResolver.commit();
+        assertFalse(resourceResolver.hasChanges());
+    }
+
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/ValueMapTest.java 
b/src/test/java/org/apache/sling/testing/resourceresolver/ValueMapTest.java
index 25b0927..f2a51e4 100644
--- a/src/test/java/org/apache/sling/testing/resourceresolver/ValueMapTest.java
+++ b/src/test/java/org/apache/sling/testing/resourceresolver/ValueMapTest.java
@@ -45,7 +45,7 @@ public class ValueMapTest {
 
     @Before
     public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
+        resourceResolver = createResourceResolver();
 
         Resource root = resourceResolver.getResource("/");
         testRoot = resourceResolver.create(root, "test", ValueMap.EMPTY);
@@ -56,6 +56,10 @@ public class ValueMapTest {
                 .build());
     }
 
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
     @SuppressWarnings("unchecked")
     @Test
     public void testMap() throws IOException {
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/CreateDeleteResourceResolverResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/CreateDeleteResourceResolverResourceProviderTest.java
index 8a11945..ddb680d 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/CreateDeleteResourceResolverResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import 
org.apache.sling.testing.resourceresolver.CreateDeleteResourceResolverTest;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class CreateDeleteResourceResolverResourceProviderTest extends 
CreateDeleteResourceResolverTest {
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/FindQueryResourcesTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/FindQueryResourcesTestResourceProviderTest.java
index 8a11945..2bf0ef8 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/FindQueryResourcesTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.FindQueryResourcesTest;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class FindQueryResourcesTestResourceProviderTest extends 
FindQueryResourcesTest {
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/IsResourceTypeTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/IsResourceTypeTestResourceProviderTest.java
index 8a11945..70b2add 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/IsResourceTypeTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.IsResourceTypeTest;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class IsResourceTypeTestResourceProviderTest extends IsResourceTypeTest 
{
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/provider/MockResourceProviderTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/MockResourceProviderTest.java
new file mode 100644
index 0000000..7600b9c
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/MockResourceProviderTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.resourceresolver.provider;
+
+import static org.junit.Assert.assertFalse;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.apache.sling.testing.resourceresolver.MockResourceResolver;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MockResourceProviderTest {
+
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
+
+    private Resource testRoot;
+
+    @Before
+    @SuppressWarnings("null")
+    public void setUp() throws Exception {
+        context.registerInjectActivateService(MockResourceProvider.class);
+
+        Resource root = context.resourceResolver().getResource("/");
+        testRoot = context.resourceResolver().create(root, "test", 
ValueMap.EMPTY);
+    }
+
+    @Test
+    public void testResourceResolverFromResource() {
+        assertFalse("testRoot.resourceResolver is not MockResourceResolver",
+                testRoot.getResourceResolver() instanceof 
MockResourceResolver);
+    }
+
+    @Test
+    public void testResourceResolverFromChildren() throws Exception {
+        context.resourceResolver().create(testRoot, "r1", ValueMap.EMPTY);
+        context.resourceResolver().create(testRoot, "r2", ValueMap.EMPTY);
+
+        Iterator<Resource> children = testRoot.listChildren();
+        while (children.hasNext()) {
+            Resource child = children.next();
+            assertFalse("testRoot.resourceResolver is not 
MockResourceResolver",
+                    child.getResourceResolver() instanceof 
MockResourceResolver);
+        }
+    }
+
+
+}
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/NtFileResourceTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/NtFileResourceTestResourceProviderTest.java
index 8a11945..17f60e2 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/NtFileResourceTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.apache.sling.testing.resourceresolver.NtFileResourceTest;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class NtFileResourceTestResourceProviderTest extends NtFileResourceTest 
{
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/RootResourceTypeTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/RootResourceTypeTestResourceProviderTest.java
index 8a11945..9470b1a 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/RootResourceTypeTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.apache.sling.testing.resourceresolver.RootResourceTypeTest;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class RootResourceTypeTestResourceProviderTest extends 
RootResourceTypeTest {
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/SlingCrudResourceResolverTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/SlingCrudResourceResolverTestResourceProviderTest.java
index 8a11945..3ed2ce9 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/SlingCrudResourceResolverTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.apache.sling.testing.resourceresolver.SlingCrudResourceResolverTest;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class SlingCrudResourceResolverTestResourceProviderTest extends 
SlingCrudResourceResolverTest {
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/ValueMapTestResourceProviderTest.java
similarity index 53%
copy from 
src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
copy to 
src/test/java/org/apache/sling/testing/resourceresolver/provider/ValueMapTestResourceProviderTest.java
index 8a11945..3ef3703 100644
--- 
a/src/test/java/org/apache/sling/testing/resourceresolver/RootResourceTypeTest.java
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/ValueMapTestResourceProviderTest.java
@@ -16,37 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.resourceresolver;
-
-import java.io.IOException;
+package org.apache.sling.testing.resourceresolver.provider;
 
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RootResourceTypeTest {
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.apache.sling.testing.resourceresolver.ValueMapTest;
+import org.junit.Rule;
 
-    private ResourceResolver resourceResolver;
+public class ValueMapTestResourceProviderTest extends ValueMapTest {
 
-    @Before
-    public final void setUp() throws IOException, LoginException {
-        resourceResolver = new 
MockResourceResolverFactory().getResourceResolver(null);
-    }
-
-    @Test
-    @SuppressWarnings("null")
-    public void testIsResourceResolver() {
-        Resource root= resourceResolver.getResource("/");
-        Assert.assertTrue(root.isResourceType("rep:root"));
-    }
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
 
-    @Test
-    public void testGetRootParent() {
-        Resource rootParent = resourceResolver.getResource("/..");
-        Assert.assertNull(rootParent);
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
     }
 
 }

Reply via email to