DATACMNS-988 - Polishing.

Added some tests.

Original Pull Request: #194
This commit is contained in:
Christoph Strobl
2017-03-10 10:28:36 +01:00
parent d72e9486be
commit c716ab839d
3 changed files with 102 additions and 41 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -18,6 +18,7 @@ package org.springframework.data.repository.core.support;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import io.reactivex.Flowable;
import reactor.core.publisher.Flux;
import rx.Observable;
@@ -30,16 +31,17 @@ import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.reactivestreams.Publisher;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.data.repository.reactive.ReactiveSortingRepository;
import org.springframework.data.repository.reactive.RxJava1CrudRepository;
import org.springframework.data.repository.reactive.RxJava2CrudRepository;
/**
* Unit tests for {@link ReactiveRepositoryInformation}.
*
* @author Mark Paluch
* @author Oliver Gierke
* @author Christoph Strobl
*/
@RunWith(MockitoJUnitRunner.class)
public class ReactiveRepositoryInformationUnitTests {
@@ -47,26 +49,38 @@ public class ReactiveRepositoryInformationUnitTests {
static final Class<ReactiveJavaInterfaceWithGenerics> REPOSITORY = ReactiveJavaInterfaceWithGenerics.class;
@Test // DATACMNS-836
public void discoversMethodWithoutComparingReturnType() throws Exception {
public void discoversRxJava1MethodWithoutComparingReturnType() throws Exception {
Method method = RxJava1InterfaceWithGenerics.class.getMethod("deleteAll");
RepositoryMetadata metadata = new DefaultRepositoryMetadata(RxJava1InterfaceWithGenerics.class);
DefaultRepositoryInformation information = new DefaultRepositoryInformation(metadata, REPOSITORY, Optional.empty());
Method reference = extractTargetMethodFromRepository(RxJava1InterfaceWithGenerics.class, "deleteAll");
Method reference = information.getTargetClassMethod(method);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("deleteAll"));
}
@Test // DATACMNS-836
public void discoversMethodWithConvertibleArguments() throws Exception {
public void discoversRxJava1MethodWithConvertibleArguments() throws Exception {
Method method = RxJava1InterfaceWithGenerics.class.getMethod("save", Observable.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(RxJava1InterfaceWithGenerics.class);
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
Optional.empty());
Method reference = extractTargetMethodFromRepository(RxJava1InterfaceWithGenerics.class, "save", Observable.class);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("save"));
assertThat(reference.getParameterTypes()[0], is(equalTo(Publisher.class)));
}
@Test // DATACMNS-988
public void discoversRxJava2MethodWithoutComparingReturnType() throws Exception {
Method reference = extractTargetMethodFromRepository(RxJava2InterfaceWithGenerics.class, "deleteAll");
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("deleteAll"));
}
@Test // DATACMNS-988
public void discoversRxJava2MethodWithConvertibleArguments() throws Exception {
Method reference = extractTargetMethodFromRepository(RxJava2InterfaceWithGenerics.class, "save", Flowable.class);
Method reference = information.getTargetClassMethod(method);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("save"));
assertThat(reference.getParameterTypes()[0], is(equalTo(Publisher.class)));
@@ -75,12 +89,8 @@ public class ReactiveRepositoryInformationUnitTests {
@Test // DATACMNS-836
public void discoversMethodAssignableArguments() throws Exception {
Method method = ReactiveSortingRepository.class.getMethod("save", Publisher.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
Optional.empty());
Method reference = extractTargetMethodFromRepository(ReactiveSortingRepository.class, "save", Publisher.class);
Method reference = information.getTargetClassMethod(method);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("save"));
assertThat(reference.getParameterTypes()[0], is(equalTo(Publisher.class)));
@@ -89,12 +99,9 @@ public class ReactiveRepositoryInformationUnitTests {
@Test // DATACMNS-836
public void discoversMethodExactIterableArguments() throws Exception {
Method method = ReactiveJavaInterfaceWithGenerics.class.getMethod("save", Iterable.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
Optional.empty());
Method reference = extractTargetMethodFromRepository(ReactiveJavaInterfaceWithGenerics.class, "save",
Iterable.class);
Method reference = information.getTargetClassMethod(method);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("save"));
assertThat(reference.getParameterTypes()[0], is(equalTo(Iterable.class)));
@@ -103,12 +110,8 @@ public class ReactiveRepositoryInformationUnitTests {
@Test // DATACMNS-836
public void discoversMethodExactObjectArguments() throws Exception {
Method method = ReactiveJavaInterfaceWithGenerics.class.getMethod("save", Object.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
Optional.empty());
Method reference = extractTargetMethodFromRepository(ReactiveJavaInterfaceWithGenerics.class, "save", Object.class);
Method reference = information.getTargetClassMethod(method);
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
assertThat(reference.getName(), is("save"));
assertThat(reference.getParameterTypes()[0], is(equalTo(Object.class)));
@@ -117,18 +120,23 @@ public class ReactiveRepositoryInformationUnitTests {
@Test // DATACMNS-1023
public void usesCorrectSaveOverload() throws Exception {
RepositoryMetadata metadata = new DefaultRepositoryMetadata(DummyRepository.class);
RepositoryInformation information = new ReactiveRepositoryInformation(metadata, ReactiveCrudRepository.class,
Optional.empty());
Method reference = extractTargetMethodFromRepository(DummyRepository.class, "save", Iterable.class);
Method method = DummyRepository.class.getMethod("save", Iterable.class);
assertThat(reference, is(ReactiveCrudRepository.class.getMethod("save", Iterable.class)));
}
assertThat(information.getTargetClassMethod(method),
is(ReactiveCrudRepository.class.getMethod("save", Iterable.class)));
private Method extractTargetMethodFromRepository(Class<?> repositoryType, String methodName, Class... args)
throws NoSuchMethodException {
RepositoryInformation information = new ReactiveRepositoryInformation(new DefaultRepositoryMetadata(repositoryType),
REPOSITORY, Optional.empty());
return information.getTargetClassMethod(repositoryType.getMethod(methodName, args));
}
interface RxJava1InterfaceWithGenerics extends RxJava1CrudRepository<User, String> {}
interface RxJava2InterfaceWithGenerics extends RxJava2CrudRepository<User, String> {}
interface ReactiveJavaInterfaceWithGenerics extends ReactiveCrudRepository<User, String> {}
static abstract class DummyGenericReactiveRepositorySupport<T, ID extends Serializable>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -17,6 +17,8 @@ package org.springframework.data.repository.core.support;
import static org.mockito.Mockito.*;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import reactor.core.publisher.Mono;
import rx.Single;
@@ -36,6 +38,7 @@ import org.springframework.data.repository.reactive.ReactiveSortingRepository;
* Unit tests for {@link RepositoryFactorySupport} using reactive wrapper types.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(MockitoJUnitRunner.Silent.class)
public class ReactiveWrapperRepositoryFactorySupportUnitTests {
@@ -63,10 +66,10 @@ public class ReactiveWrapperRepositoryFactorySupportUnitTests {
}
@Test // DATACMNS-836
public void callsMethodOnBaseImplementationWithExactArguments() {
public void callsRxJava1MethodOnBaseImplementationWithExactArguments() {
Serializable id = 1L;
ConvertingRepository repository = factory.getRepository(ConvertingRepository.class);
RxJava1ConvertingRepository repository = factory.getRepository(RxJava1ConvertingRepository.class);
repository.exists(id);
repository.exists((Long) id);
@@ -75,17 +78,38 @@ public class ReactiveWrapperRepositoryFactorySupportUnitTests {
@Test // DATACMNS-836
@SuppressWarnings("unchecked")
public void callsMethodOnBaseImplementationWithTypeConversion() {
public void callsRxJava1MethodOnBaseImplementationWithTypeConversion() {
Single<Long> ids = Single.just(1L);
ConvertingRepository repository = factory.getRepository(ConvertingRepository.class);
RxJava1ConvertingRepository repository = factory.getRepository(RxJava1ConvertingRepository.class);
repository.exists(ids);
verify(backingRepo, times(1)).exists(any(Mono.class));
}
interface ConvertingRepository extends Repository<Object, Long> {
@Test // DATACMNS-988
public void callsRxJava2MethodOnBaseImplementationWithExactArguments() {
Long id = 1L;
RxJava2ConvertingRepository repository = factory.getRepository(RxJava2ConvertingRepository.class);
repository.findOne(id);
verify(backingRepo, times(1)).findOne(id);
}
@Test // DATACMNS-988
public void callsRxJava2MethodOnBaseImplementationWithTypeConversion() {
Serializable id = 1L;
RxJava2ConvertingRepository repository = factory.getRepository(RxJava2ConvertingRepository.class);
repository.delete(id);
verify(backingRepo, times(1)).delete(id);
}
interface RxJava1ConvertingRepository extends Repository<Object, Long> {
Single<Boolean> exists(Single<Long> id);
@@ -94,6 +118,15 @@ public class ReactiveWrapperRepositoryFactorySupportUnitTests {
Single<Boolean> exists(Long id);
}
interface RxJava2ConvertingRepository extends Repository<Object, Long> {
Maybe<Boolean> findOne(Serializable id);
Single<Boolean> exists(Long id);
Completable delete(Serializable id);
}
interface ObjectRepository
extends Repository<Object, Serializable>, RepositoryFactorySupportUnitTests.ObjectRepositoryCustom {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2017 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.
@@ -18,6 +18,7 @@ package org.springframework.data.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import io.reactivex.Flowable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import rx.Observable;
@@ -48,6 +49,7 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat
*
* @author Oliver Gierke
* @author Mark Paluch
* @author Christoph Strobl
*/
public class ResultProcessorUnitTests {
@@ -290,6 +292,22 @@ public class ResultProcessorUnitTests {
assertThat(content.get(0)).isInstanceOf(SampleProjection.class);
}
@Test // DATACMNS-988
@SuppressWarnings("unchecked")
public void supportsFlowableProjections() throws Exception {
Flowable<Sample> samples = Flowable.just(new Sample("Dave", "Matthews"));
Object result = getProcessor("findFlowableProjection").processResult(samples);
assertThat(result).isInstanceOf(Flowable.class);
List<Object> content = ((Flowable<Object>) result).toList().blockingGet();
assertThat(content).isNotEmpty();
assertThat(content.get(0)).isInstanceOf(SampleProjection.class);
}
private static ResultProcessor getProcessor(String methodName, Class<?>... parameters) throws Exception {
return getQueryMethod(methodName, parameters).getResultProcessor();
}
@@ -336,6 +354,8 @@ public class ResultProcessorUnitTests {
Flux<SampleProjection> findFluxProjection();
Observable<SampleProjection> findObservableProjection();
Flowable<SampleProjection> findFlowableProjection();
}
static class Sample {