diff --git a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java index 3e04230..743e1cb 100644 --- a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java +++ b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java @@ -23,6 +23,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -126,6 +128,9 @@ import org.apache.geode.cache.query.IndexStatistics; import org.apache.geode.cache.query.Query; import org.apache.geode.cache.query.QueryService; import org.apache.geode.cache.query.QueryStatistics; +import org.apache.geode.cache.query.SelectResults; +import org.apache.geode.cache.query.types.CollectionType; +import org.apache.geode.cache.query.types.ObjectType; import org.apache.geode.cache.server.CacheServer; import org.apache.geode.cache.server.ClientSubscriptionConfig; import org.apache.geode.cache.server.ServerLoadProbe; @@ -1809,10 +1814,11 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { QueryService mockQueryService = mockQueryService(); - when(regionService.getQueryService()).thenReturn(mockQueryService); + doReturn(mockQueryService).when(regionService).getQueryService(); if (regionService instanceof ClientCache) { - when(((ClientCache) regionService).getLocalQueryService()).thenReturn(mockQueryService); + doReturn(mockQueryService).when((ClientCache) regionService).getLocalQueryService(); + doReturn(mockQueryService).when((ClientCache) regionService).getQueryService(anyString()); } return regionService; @@ -1827,12 +1833,13 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { Set indexes = Collections.synchronizedSet(new HashSet<>()); try { - when(mockQueryService.getCqs()).thenAnswer(invocation -> cqQueries.toArray(new CqQuery[cqQueries.size()])); when(mockQueryService.getCq(anyString())).thenAnswer(invocation -> cqQueries.stream().filter(cqQuery -> invocation.getArgument(0).equals(cqQuery.getName())) .findFirst().orElse(null)); + when(mockQueryService.getCqs()).thenAnswer(invocation -> cqQueries.toArray(new CqQuery[cqQueries.size()])); + when(mockQueryService.getCqs(anyString())).thenAnswer(invocation -> { List cqQueriesByRegion = cqQueries.stream().filter(cqQuery -> { @@ -1856,18 +1863,6 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { return cqQueriesByRegion.toArray(new CqQuery[cqQueriesByRegion.size()]); }); - when(mockQueryService.getIndexes()).thenReturn(indexes); - - when(mockQueryService.getIndexes(any(Region.class))).thenAnswer(invocation -> { - - Region region = invocation.getArgument(0); - - return indexes.stream() - .filter(index -> index.getRegion().equals(region)) - .collect(Collectors.toList()); - - }); - when(mockQueryService.getIndex(any(Region.class), anyString())).thenAnswer(invocation -> { Region region = invocation.getArgument(0); @@ -1882,6 +1877,18 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { }); + when(mockQueryService.getIndexes()).thenReturn(indexes); + + when(mockQueryService.getIndexes(any(Region.class))).thenAnswer(invocation -> { + + Region region = invocation.getArgument(0); + + return indexes.stream() + .filter(index -> index.getRegion().equals(region)) + .collect(Collectors.toList()); + + }); + when(mockQueryService.createIndex(anyString(), anyString(), anyString())) .thenAnswer(createIndexAnswer(indexes, IndexType.FUNCTIONAL)); @@ -1912,6 +1919,10 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { when(mockQueryService.newCq(anyString(), anyString(), any(CqAttributes.class), anyBoolean())) .thenAnswer(invocation -> add(cqQueries, mockCqQuery(invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2), invocation.getArgument(3)))); + + when(mockQueryService.newQuery(anyString())) + .thenAnswer(invocation -> mockQuery(invocation.getArgument(0))); + } catch (Exception cause) { throw new MockObjectInvocationException(cause); @@ -2000,8 +2011,20 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { QueryStatistics mockQueryStatistics = mockQueryStatistics(mockQuery); - when(mockQuery.getQueryString()).thenReturn(queryString); - when(mockQuery.getStatistics()).thenReturn(mockQueryStatistics); + SelectResults mockSelectResults = mockSelectResults(); + + doReturn(queryString).when(mockQuery).getQueryString(); + doReturn(mockQueryStatistics).when(mockQuery).getStatistics(); + + try { + doReturn(mockSelectResults).when(mockQuery).execute(); + doReturn(mockSelectResults).when(mockQuery).execute(any(Object.class)); + doReturn(mockSelectResults).when(mockQuery).execute(any(RegionFunctionContext.class)); + doReturn(mockSelectResults).when(mockQuery).execute(any(RegionFunctionContext.class), any()); + } + catch (Throwable cause) { + throw new MockObjectInvocationException(cause); + } return mockQuery; } @@ -2033,6 +2056,34 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { return mockQueryStatistics; } + public static SelectResults mockSelectResults() { + + ObjectType mockObjectType = mock(ObjectType.class, withSettings().lenient()); + + doReturn(Object.class.getSimpleName()).when(mockObjectType).getSimpleClassName(); + doReturn(false).when(mockObjectType).isCollectionType(); + doReturn(false).when(mockObjectType).isMapType(); + doReturn(false).when(mockObjectType).isStructType(); + doReturn(Object.class).when(mockObjectType).resolveClass(); + + CollectionType mockCollectionType = mock(CollectionType.class, withSettings().lenient()); + + doReturn(false).when(mockCollectionType).allowsDuplicates(); + doReturn(mockObjectType).when(mockCollectionType).getElementType(); + doReturn(false).when(mockCollectionType).isOrdered(); + + SelectResults mockSelectResults = mock(SelectResults.class, withSettings().lenient()); + + doReturn(Collections.emptyList()).when(mockSelectResults).asList(); + doReturn(Collections.emptySet()).when(mockSelectResults).asSet(); + doReturn(mockCollectionType).when(mockSelectResults).getCollectionType(); + doReturn(false).when(mockSelectResults).isModifiable(); + doReturn(0).when(mockSelectResults).occurrences(any()); + doNothing().when(mockSelectResults).setElementType(any(ObjectType.class)); + + return mockSelectResults; + } + public static Index mockIndex(String name, String expression, String fromClause, IndexType indexType) { Index mockIndex = mock(Index.class, name); diff --git a/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/MockCacheQueryServiceInteractionsUnitTests.java b/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/MockCacheQueryServiceInteractionsUnitTests.java new file mode 100644 index 0000000..6c02fb0 --- /dev/null +++ b/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/MockCacheQueryServiceInteractionsUnitTests.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.gemfire.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import org.apache.geode.cache.GemFireCache; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.query.Query; +import org.apache.geode.cache.query.QueryService; +import org.apache.geode.cache.query.SelectResults; +import org.apache.geode.cache.query.types.CollectionType; +import org.apache.geode.cache.query.types.ObjectType; + +import org.springframework.data.gemfire.tests.mock.GemFireMockObjectsSupport; + +/** + * Unit Tests for GemFire/Geode {@literal Mock} {@link GemFireCache} {@link QueryService} and {@link Query OQL Queries}. + * + * @author John Blum + * @see org.junit.Test + * @see org.apache.geode.cache.GemFireCache + * @see org.apache.geode.cache.client.ClientCache + * @see org.apache.geode.cache.query.QueryService + * @see org.apache.geode.cache.query.Query + * @see org.apache.geode.cache.query.SelectResults + * @see org.apache.geode.cache.query.types.CollectionType + * @see org.apache.geode.cache.query.types.ObjectType + * @since 0.0.19 + */ +public class MockCacheQueryServiceInteractionsUnitTests { + + private void assertSelectResults(SelectResults selectResults) { + + assertThat(selectResults).isNotNull(); + assertThat(selectResults.asList()).isEmpty(); + assertThat(selectResults.asSet()).isEmpty(); + assertThat(selectResults.isModifiable()).isFalse(); + assertThat(selectResults.occurrences("MOCK")).isZero(); + assertThat(selectResults.occurrences("TEST")).isZero(); + + CollectionType collectionType = selectResults.getCollectionType(); + + assertThat(collectionType).isNotNull(); + assertThat(collectionType.allowsDuplicates()).isFalse(); + assertThat(collectionType.isOrdered()).isFalse(); + + ObjectType objectType = collectionType.getElementType(); + + assertThat(objectType).isNotNull(); + assertThat(objectType.getSimpleClassName()).isEqualTo(Object.class.getSimpleName()); + assertThat(objectType.isCollectionType()).isFalse(); + assertThat(objectType.isMapType()).isFalse(); + assertThat(objectType.isStructType()).isFalse(); + assertThat(objectType.resolveClass()).isEqualTo(Object.class); + } + + @Test + @SuppressWarnings("unchecked") + public void queryServiceInteractionsAndQueryExecutionIsCorrect() throws Exception { + + String queryString = "SELECT * FROM /Example WHERE id = $1"; + + ClientCache mockClientCache = GemFireMockObjectsSupport.mockClientCache(); + + assertThat(mockClientCache).isNotNull(); + + QueryService mockQueryService = mockClientCache.getQueryService(); + + assertThat(mockQueryService).isNotNull(); + + Query mockQuery = mockQueryService.newQuery(queryString); + + assertThat(mockQuery).isNotNull(); + assertThat(mockQuery.getQueryString()).isEqualTo(queryString); + assertThat(mockQuery.getStatistics()).isNotNull(); + + Object results = mockQuery.execute(); + + assertThat(results).isInstanceOf(SelectResults.class); + + SelectResults mockSelectResults = (SelectResults) results; + + assertSelectResults(mockSelectResults); + + results = mockQuery.execute(1); + + assertThat(results).isInstanceOf(SelectResults.class); + + mockSelectResults = (SelectResults) results; + + assertSelectResults(mockSelectResults); + } +}