You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:17:51 UTC

[sling-org-apache-sling-testing-jcr-mock] 13/17: SLING-4230 Add support for mocking queries and query results

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

rombert pushed a commit to annotated tag org.apache.sling.testing.jcr-mock-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-jcr-mock.git

commit 10fb5605469b7a281a34bc03e8694a39f5f06df5
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Tue Dec 9 15:32:02 2014 +0000

    SLING-4230 Add support for mocking queries and query results
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/jcr-mock@1644089 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/testing/mock/jcr/MockJcr.java |  50 +++++
 .../apache/sling/testing/mock/jcr/MockQuery.java   | 115 ++++++++++++
 .../sling/testing/mock/jcr/MockQueryManager.java   |  90 +++++++++
 .../sling/testing/mock/jcr/MockQueryResult.java    |  84 +++++++++
 .../testing/mock/jcr/MockQueryResultHandler.java   |  37 ++++
 .../org/apache/sling/testing/mock/jcr/MockRow.java |  92 ++++++++++
 .../sling/testing/mock/jcr/MockWorkspace.java      |  11 +-
 .../testing/mock/jcr/MockQueryManagerTest.java     | 204 +++++++++++++++++++++
 8 files changed, 678 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockJcr.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockJcr.java
index 530a51f..08d54aa 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockJcr.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockJcr.java
@@ -18,16 +18,23 @@
  */
 package org.apache.sling.testing.mock.jcr;
 
+import java.util.List;
+
+import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.query.QueryManager;
 
 import org.apache.commons.lang3.StringUtils;
 
+import aQute.bnd.annotation.ConsumerType;
+
 /**
  * Factory for mock JCR objects.
  */
+@ConsumerType
 public final class MockJcr {
 
     /**
@@ -81,5 +88,48 @@ public final class MockJcr {
             throw new RuntimeException("Creating mocked JCR session failed.", ex);
         }
     }
+    
+    /**
+     * Sets the expected result list for all queries executed with the given query manager.
+     * @param queryManager Mocked query manager
+     * @param resultList Result list
+     */
+    public static void setQueryResult(final QueryManager queryManager, final List<Node> resultList) {
+        addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                return new MockQueryResult(resultList);
+            }
+        });
+    }
+
+    /**
+     * Sets the expected result list for all queries with the given statement executed with the given query manager.
+     * @param queryManager Mocked query manager
+     * @param statement Query statement
+     * @param resultList Result list
+     */
+    public static void setQueryResult(final QueryManager queryManager, final String statement, final List<Node> resultList) {
+        addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                if (StringUtils.equals(query.getStatement(), statement)) {
+                    return new MockQueryResult(resultList);
+                }
+                else {
+                    return null;
+                }
+            }
+        });
+    }
+
+    /**
+     * Adds a query result handler for the given query manager which may return query results for certain queries that are executed.
+     * @param queryManager Mocked query manager
+     * @param resultHandler Mock query result handler
+     */
+    public static void addQueryResultHandler(final QueryManager queryManager, final MockQueryResultHandler resultHandler) {
+        ((MockQueryManager)queryManager).addResultHandler(resultHandler);
+    }
 
 }
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockQuery.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockQuery.java
new file mode 100644
index 0000000..3e9faa4
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockQuery.java
@@ -0,0 +1,115 @@
+/*
+ * 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.mock.jcr;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Value;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
+
+import aQute.bnd.annotation.ConsumerType;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Mock implementation of {@link Query}.
+ */
+@ConsumerType
+public final class MockQuery implements Query {
+    
+    private final MockQueryManager queryManager;
+    private final String statement;
+    private final String language;
+    
+    private long limit;
+    private long offset;
+    private Map<String,Value> variables = new HashMap<String, Value>();
+    
+    MockQuery(MockQueryManager queryManager, String statement, String language) {
+        this.queryManager = queryManager;
+        this.statement = statement;
+        this.language = language;
+    }
+
+    @Override
+    public QueryResult execute() {
+        return queryManager.executeQuery(this);
+    }
+
+    @Override
+    public void setLimit(long limit) {
+        this.limit = limit;
+    }
+
+    public long getLimit() {
+        return limit;
+    }
+
+    @Override
+    public void setOffset(long offset) {
+        this.offset = offset;
+    }
+
+    public long getOffset() {
+        return offset;
+    }
+
+    @Override
+    public String getStatement() {
+        return this.statement;
+    }
+
+    @Override
+    public String getLanguage() {
+        return this.language;
+    }
+
+    @Override
+    public void bindValue(String varName, Value value) {
+        variables.put(varName,  value);
+    }
+
+    @Override
+    public String[] getBindVariableNames() {
+        Set<String> variableNames = variables.keySet();
+        return variableNames.toArray(new String[variableNames.size()]);
+    }
+    
+    public Map<String, Value> getBindVariables() {
+        return ImmutableMap.copyOf(variables);
+    }
+    
+
+    // --- unsupported operations ---
+
+    @Override
+    public String getStoredQueryPath() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Node storeAsNode(String absPath) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryManager.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryManager.java
new file mode 100644
index 0000000..02f1eca
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryManager.java
@@ -0,0 +1,90 @@
+/*
+ * 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.mock.jcr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.qom.QueryObjectModelFactory;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Mock implementation of {@link QueryManager}.
+ */
+class MockQueryManager implements QueryManager {
+    
+    private List<MockQueryResultHandler> resultHandlers = new ArrayList<MockQueryResultHandler>();
+    
+    @SuppressWarnings("deprecation")
+    private static final List<String> SUPPORTED_QUERY_LANGUAGES = ImmutableList.of(
+      Query.JCR_SQL2,
+      Query.JCR_JQOM,
+      Query.XPATH,
+      Query.SQL
+    );
+    
+    @Override
+    public Query createQuery(String statement, String language) throws InvalidQueryException {
+        if (!SUPPORTED_QUERY_LANGUAGES.contains(StringUtils.defaultString(language))) {
+            throw new InvalidQueryException("Unsupported query language: " + language);
+        }
+        return new MockQuery(this, statement, language);
+    }
+
+    @Override
+    public String[] getSupportedQueryLanguages() {
+        return SUPPORTED_QUERY_LANGUAGES.toArray(new String[SUPPORTED_QUERY_LANGUAGES.size()]);
+    }
+    
+    void addResultHandler(MockQueryResultHandler resultHandler) {
+        this.resultHandlers.add(resultHandler);
+    }
+    
+    QueryResult executeQuery(MockQuery query) {
+        for (MockQueryResultHandler resultHandler : resultHandlers) {
+            MockQueryResult result = resultHandler.executeQuery(query);
+            if (result != null) {
+                return result;
+            }
+        }
+        // fallback to empty result
+        return new MockQueryResult(ImmutableList.<Node>of());
+    }
+
+    // --- unsupported operations ---
+    
+    @Override
+    public QueryObjectModelFactory getQOMFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Query getQuery(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResult.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResult.java
new file mode 100644
index 0000000..6d7d486
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResult.java
@@ -0,0 +1,84 @@
+/*
+ * 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.mock.jcr;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.Row;
+import javax.jcr.query.RowIterator;
+
+import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
+import org.apache.jackrabbit.commons.iterator.RowIteratorAdapter;
+
+import aQute.bnd.annotation.ProviderType;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * Mock implementation of {@link QueryResult}.
+ * Allows to manually set the expected result, optional with column names 
+ * (which are interpreted as property names of the nodes of the result list).
+ */
+@ProviderType
+public final class MockQueryResult implements QueryResult {
+    
+    private final List<Node> nodes;
+    private final List<String> columnNames;
+    
+    public MockQueryResult(List<Node> nodes) {
+        this(nodes, ImmutableList.<String>of());
+    }
+
+    public MockQueryResult(List<Node> nodes, List<String> columnNames) {
+        this.columnNames = columnNames;
+        this.nodes = nodes;
+    }
+
+    @Override
+    public String[] getColumnNames() throws RepositoryException {
+        return columnNames.toArray(new String[columnNames.size()]);
+    }
+
+    @Override
+    public RowIterator getRows() throws RepositoryException {
+        return new RowIteratorAdapter(Lists.transform(nodes, new Function<Node, Row>() {
+            @Override
+            public Row apply(Node node) {
+                return new MockRow(columnNames, node);
+            }
+        }));
+    }
+
+    @Override
+    public NodeIterator getNodes() throws RepositoryException {
+        return new NodeIteratorAdapter(nodes);
+    }
+
+    @Override
+    public String[] getSelectorNames() throws RepositoryException {
+        return new String[0];
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResultHandler.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResultHandler.java
new file mode 100644
index 0000000..7408565
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockQueryResultHandler.java
@@ -0,0 +1,37 @@
+/*
+ * 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.mock.jcr;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Allows to set mocked query results for a mocked {@link javax.jcr.query.QueryManager}.
+ */
+@ConsumerType
+public interface MockQueryResultHandler {
+
+    /**
+     * Checks if this handler accepts the given query, and returns the result if this is the case.
+     * @param query Query that is executed
+     * @return Query result if the query can be executed by this handler.
+     *   If not, null is returned and other handlers are asked to provide a result.
+     */
+    MockQueryResult executeQuery(MockQuery query);
+    
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockRow.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockRow.java
new file mode 100644
index 0000000..6f19367
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockRow.java
@@ -0,0 +1,92 @@
+/*
+ * 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.mock.jcr;
+
+import java.util.List;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.query.Row;
+
+/**
+ * Mock implementation of {@link Row}.
+ */
+class MockRow implements Row {
+    
+    private final List<String> columnNames;
+    private final Node node;
+    
+    public MockRow(List<String> columnNames, Node node) {
+        this.columnNames = columnNames;
+        this.node = node;
+    }
+
+    @Override
+    public Value[] getValues() throws RepositoryException {
+        Value[] values = new Value[columnNames.size()];
+        for (int i = 0; i < values.length; i++) {
+            try {
+                values[i] = getValue(columnNames.get(i));
+            }
+            catch (PathNotFoundException ex) {
+                values[i] = null;
+            }
+        }
+        return values;
+    }
+
+    @Override
+    public Value getValue(String columnName) throws ItemNotFoundException, RepositoryException {
+        return node.getProperty(columnName).getValue();
+    }
+
+    @Override
+    public Node getNode() throws RepositoryException {
+        return node;
+    }
+
+    @Override
+    public Node getNode(String selectorName) throws RepositoryException {
+        return null;
+    }
+
+    @Override
+    public String getPath() throws RepositoryException {
+        return node.getPath();
+    }
+
+    @Override
+    public String getPath(String selectorName) throws RepositoryException {
+        return null;
+    }
+
+    @Override
+    public double getScore() throws RepositoryException {
+        return 0;
+    }
+
+    @Override
+    public double getScore(String selectorName) throws RepositoryException {
+        return 0;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockWorkspace.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockWorkspace.java
index 329a760..635f280 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockWorkspace.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockWorkspace.java
@@ -42,6 +42,7 @@ class MockWorkspace implements Workspace {
     private final NamespaceRegistry namespaceRegistry = new MockNamespaceRegistry();
     private final ObservationManager observationManager = new MockObservationManager();
     private final NodeTypeManager nodeTypeManager = new MockNodeTypeManager();
+    private final QueryManager queryManager = new MockQueryManager();
 
     /**
      * @param session JCR session
@@ -76,6 +77,11 @@ class MockWorkspace implements Workspace {
         return this.nodeTypeManager;
     }
 
+    @Override
+    public QueryManager getQueryManager() {
+        return this.queryManager;
+    }
+    
     // --- unsupported operations ---
     @Override
     public void copy(final String srcAbsPath, final String destAbsPath) {
@@ -109,11 +115,6 @@ class MockWorkspace implements Workspace {
     }
 
     @Override
-    public QueryManager getQueryManager() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public VersionManager getVersionManager() {
         throw new UnsupportedOperationException();
     }
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockQueryManagerTest.java b/src/test/java/org/apache/sling/testing/mock/jcr/MockQueryManagerTest.java
new file mode 100644
index 0000000..413c55e
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockQueryManagerTest.java
@@ -0,0 +1,204 @@
+/*
+ * 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.mock.jcr;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.Row;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class MockQueryManagerTest {
+
+    private Session session;
+    private QueryManager queryManager;
+    private List<Node> sampleNodes;
+    
+    @Before
+    public void setUp() throws RepositoryException {
+        session = MockJcr.newSession();
+        queryManager = session.getWorkspace().getQueryManager();
+        
+        Node rootNode = session.getRootNode();
+        
+        sampleNodes = ImmutableList.of(
+            rootNode.addNode("node1"),
+            rootNode.addNode("node2"),
+            rootNode.addNode("node3")
+        );
+        
+        for (int i=0; i<sampleNodes.size(); i++) { 
+            Node node = sampleNodes.get(i);
+            node.setProperty("stringProp", "value" + (i + 1));
+            node.setProperty("intProp", i + 1);
+        }
+        sampleNodes.get(0).setProperty("optionalStringProp", "optValue1");
+    }
+    
+    @Test
+    public void testNoQueryResults() throws RepositoryException {
+        Query query = queryManager.createQuery("dummy", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertFalse(result.getNodes().hasNext());
+    }
+    
+    @Test(expected=InvalidQueryException.class)
+    public void testInvalidQueryLanguage() throws RepositoryException {
+        queryManager.createQuery("dummy", "wurst");
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testQueryResults_AllQuerys() throws RepositoryException {
+        MockJcr.setQueryResult(queryManager, sampleNodes);
+        
+        Query query = queryManager.createQuery("query1", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+
+        query = queryManager.createQuery("query2", Query.JCR_SQL2);
+        result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testQueryResults_SpecificQuery() throws RepositoryException {
+        MockJcr.setQueryResult(queryManager, "query1", sampleNodes);
+        
+        Query query = queryManager.createQuery("query1", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+
+        query = queryManager.createQuery("query2", Query.JCR_SQL2);
+        result = query.execute();
+        assertFalse(result.getNodes().hasNext());
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testQueryResults_ResultHandler() throws RepositoryException {
+        MockJcr.addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                if (StringUtils.equals(query.getStatement(), "query1")) {
+                    return new MockQueryResult(sampleNodes);
+                }
+                return null;
+            }
+        });
+        
+        Query query = queryManager.createQuery("query1", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+
+        query = queryManager.createQuery("query2", Query.JCR_SQL2);
+        result = query.execute();
+        assertFalse(result.getNodes().hasNext());
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testQueryResults_MultipleResultHandlers() throws RepositoryException {
+        final List<Node> sampleNodes2 = ImmutableList.of(sampleNodes.get(0));
+        MockJcr.addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                if (StringUtils.equals(query.getStatement(), "query2")) {
+                    return new MockQueryResult(sampleNodes2);
+                }
+                return null;
+            }
+        });
+        
+        MockJcr.addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                if (StringUtils.equals(query.getStatement(), "query1")) {
+                    return new MockQueryResult(sampleNodes);
+                }
+                return null;
+            }
+        });
+        
+        Query query = queryManager.createQuery("query1", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+
+        query = queryManager.createQuery("query2", Query.JCR_SQL2);
+        result = query.execute();
+        assertEquals(sampleNodes2, ImmutableList.copyOf(result.getNodes()));
+
+        query = queryManager.createQuery("query3", Query.JCR_SQL2);
+        result = query.execute();
+        assertFalse(result.getNodes().hasNext());
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testQueryResults_ResultHandler_Rows() throws RepositoryException {
+        final List<String> columnNames = ImmutableList.of(
+            "stringProp",
+            "intProp",
+            "optionalStringProp"
+        );
+         
+        MockJcr.addQueryResultHandler(queryManager, new MockQueryResultHandler() {
+            @Override
+            public MockQueryResult executeQuery(MockQuery query) {
+                return new MockQueryResult(sampleNodes, columnNames);
+            }
+        });
+        
+        Query query = queryManager.createQuery("query1", Query.JCR_SQL2);
+        QueryResult result = query.execute();
+        assertEquals(sampleNodes, ImmutableList.copyOf(result.getNodes()));
+        
+        assertEquals(columnNames, ImmutableList.copyOf(result.getColumnNames()));
+        
+        List<Row> rows = ImmutableList.copyOf(result.getRows());
+        assertEquals("value1", rows.get(0).getValue("stringProp").getString());
+        assertEquals(1L, rows.get(0).getValue("intProp").getLong());
+        assertEquals("optValue1", rows.get(0).getValue("optionalStringProp").getString());
+
+        assertEquals("value2", rows.get(1).getValues()[0].getString());
+        assertEquals(2L, rows.get(1).getValues()[1].getLong());
+        assertNull(rows.get(1).getValues()[2]);
+
+        assertEquals("value3", rows.get(2).getValues()[0].getString());
+        assertEquals(3L, rows.get(2).getValues()[1].getLong());
+        assertNull(rows.get(2).getValues()[2]);
+    }
+    
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.