From b6feb47574f655d348289fb027c73b28b7f856a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Fri, 17 Feb 2017 09:55:33 -0500 Subject: [PATCH 1/2] Add @DataNeo4jTest This commit adds test infrastructure for Neo4j repositories through `@DataNeo4jTest`. See gh-8618 --- spring-boot-test-autoconfigure/pom.xml | 11 ++ .../data/neo4j/AutoConfigureDataNeo4j.java | 43 +++++++ .../data/neo4j/DataNeo4jTest.java | 95 +++++++++++++++ .../neo4j/DataNeo4jTypeExcludeFilter.java | 73 ++++++++++++ .../main/resources/META-INF/spring.factories | 6 + .../neo4j/DataNeo4jTestIntegrationTests.java | 73 ++++++++++++ ...TestWithIncludeFilterIntegrationTests.java | 52 ++++++++ .../data/neo4j/ExampleGraph.java | 52 ++++++++ .../data/neo4j/ExampleNeo4jApplication.java | 29 +++++ .../data/neo4j/ExampleRepository.java | 27 +++++ .../data/neo4j/ExampleService.java | 40 +++++++ .../boot/neo4j/Neo4jTestServer.java | 111 ++++++++++++++++++ .../boot/neo4j/package-info.java | 20 ++++ 13 files changed, 632 insertions(+) create mode 100644 spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/AutoConfigureDataNeo4j.java create mode 100644 spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java create mode 100644 spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleNeo4jApplication.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java create mode 100644 spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java create mode 100644 spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java diff --git a/spring-boot-test-autoconfigure/pom.xml b/spring-boot-test-autoconfigure/pom.xml index 5bc4a376af..7c51013c0b 100644 --- a/spring-boot-test-autoconfigure/pom.xml +++ b/spring-boot-test-autoconfigure/pom.xml @@ -121,6 +121,11 @@ spring-data-mongodb true + + org.springframework.data + spring-data-neo4j + true + org.springframework.restdocs spring-restdocs-mockmvc @@ -212,5 +217,11 @@ de.flapdoodle.embed.mongo test + + org.springframework.boot + spring-boot + test-jar + test + diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/AutoConfigureDataNeo4j.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/AutoConfigureDataNeo4j.java new file mode 100644 index 0000000000..bd7c5dcb6d --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/AutoConfigureDataNeo4j.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; + +/** + * {@link ImportAutoConfiguration Auto-configuration imports} for typical Data Neo4j + * tests. Most tests should consider using {@link DataNeo4jTest @DataNeo4jTest} rather + * than using this annotation directly. + * + * @author Eddú Meléndez + * @since 2.0.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ImportAutoConfiguration +public @interface AutoConfigureDataNeo4j { + +} diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java new file mode 100644 index 0000000000..37650a922b --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; +import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache; +import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters; +import org.springframework.boot.test.context.SpringBootTestContextBootstrapper; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.core.annotation.AliasFor; +import org.springframework.test.context.BootstrapWith; +import org.springframework.transaction.annotation.Transactional; + +/** + * Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)} + * for a typical Neo4j test. Can be used when a test focuses only on + * Neo4j components. + *

+ * Using this annotation will disable full auto-configuration and instead apply only + * configuration relevant to Neo4j tests. + *

+ * By default, tests annotated with {@code @DataNeo4jTest} will use an embedded in-memory + * Neo4j process (if available). + * + * @author Eddú Meléndez + * @since 2.0.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@BootstrapWith(SpringBootTestContextBootstrapper.class) +@OverrideAutoConfiguration(enabled = false) +@TypeExcludeFilters(DataNeo4jTypeExcludeFilter.class) +@Transactional +@AutoConfigureCache +@AutoConfigureDataNeo4j +@ImportAutoConfiguration +public @interface DataNeo4jTest { + + /** + * Determines if default filtering should be used with + * {@link SpringBootApplication @SpringBootApplication}. By default no beans are + * included. + * @see #includeFilters() + * @see #excludeFilters() + * @return if default filters should be used + */ + boolean useDefaultFilters() default true; + + /** + * A set of include filters which can be used to add otherwise filtered beans to the + * application context. + * @return include filters to apply + */ + Filter[] includeFilters() default {}; + + /** + * A set of exclude filters which can be used to filter beans that would otherwise be + * added to the application context. + * @return exclude filters to apply + */ + Filter[] excludeFilters() default {}; + + /** + * Auto-configuration exclusions that should be applied for this test. + * @return auto-configuration exclusions to apply + */ + @AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude") + Class[] excludeAutoConfiguration() default {}; + +} diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java new file mode 100644 index 0000000000..a19ca74bd5 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import java.util.Collections; +import java.util.Set; + +import org.springframework.boot.context.TypeExcludeFilter; +import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.core.annotation.AnnotatedElementUtils; + +/** + * {@link TypeExcludeFilter} for {@link DataNeo4jTest @DataNeo4jTest}. + * + * @author Eddú Meléndez + * @since 2.0.0 + */ +class DataNeo4jTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter { + + private final DataNeo4jTest annotation; + + DataNeo4jTypeExcludeFilter(final Class testClass) { + this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass, + DataNeo4jTest.class); + } + + @Override + protected boolean hasAnnotation() { + return this.annotation != null; + } + + @Override + protected Filter[] getFilters(FilterType type) { + switch (type) { + case INCLUDE: + return this.annotation.includeFilters(); + case EXCLUDE: + return this.annotation.excludeFilters(); + default: + throw new IllegalStateException("Unsupported type " + type); + } + } + + @Override + protected boolean isUseDefaultFilters() { + return this.annotation.useDefaultFilters(); + } + + @Override + protected Set> getDefaultIncludes() { + return Collections.emptySet(); + } + + @Override + protected Set> getComponentIncludes() { + return Collections.emptySet(); + } +} diff --git a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories index d76b8e9fe8..ce5e343741 100644 --- a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories @@ -23,6 +23,12 @@ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration +# AutoConfigureDataNeo4j auto-configuration imports +org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j=\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ +org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration + # AutoConfigureJdbc auto-configuration imports org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc=\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java new file mode 100644 index 0000000000..6941fcc7ff --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.neo4j.ogm.session.Session; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.neo4j.Neo4jTestServer; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Sample test for {@link DataNeo4jTest @DataNeo4jTest} + * + * @author Eddú Meléndez + */ +@RunWith(SpringRunner.class) +@DataNeo4jTest +public class DataNeo4jTestIntegrationTests { + + @Rule + public Neo4jTestServer server = new Neo4jTestServer( + new String[]{"org.springframework.boot.test.autoconfigure.data.neo4j"}); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Autowired + private Session session; + + @Autowired + private ExampleRepository exampleRepository; + + @Autowired + private ApplicationContext applicationContext; + + @Test + public void testRepository() { + ExampleGraph exampleGraph = new ExampleGraph(); + exampleGraph.setDescription("Look, new @DataNeo4jTest!"); + exampleGraph = this.exampleRepository.save(exampleGraph); + assertThat(exampleGraph.getId()).isNotNull(); + assertThat(this.session.countEntitiesOfType(ExampleGraph.class)).isEqualTo(1); + } + + @Test + public void didNotInjectExampleService() { + this.thrown.expect(NoSuchBeanDefinitionException.class); + this.applicationContext.getBean(ExampleService.class); + } + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java new file mode 100644 index 0000000000..4851a422c1 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.neo4j.Neo4jTestServer; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.stereotype.Service; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test with custom include filter for {@link DataNeo4jTest}. + * + * @author Eddú Meléndez + */ +@RunWith(SpringRunner.class) +@DataNeo4jTest(includeFilters = @Filter(Service.class)) +public class DataNeo4jTestWithIncludeFilterIntegrationTests { + + @Rule + public Neo4jTestServer server = new Neo4jTestServer( + new String[]{"org.springframework.boot.test.autoconfigure.data.neo4j"}); + + @Autowired + private ExampleService service; + + @Test + public void testService() { + assertThat(this.service.hasNode(ExampleGraph.class)).isFalse(); + } + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java new file mode 100644 index 0000000000..43753d8067 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.neo4j.ogm.annotation.GraphId; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Property; + +/** + * Example graph used with {@link DataNeo4jTest} tests. + * + * @author Eddú Meléndez + */ +@NodeEntity +public class ExampleGraph { + + @GraphId + private Long id; + + @Property + private String description; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleNeo4jApplication.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleNeo4jApplication.java new file mode 100644 index 0000000000..fdd8a8e194 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleNeo4jApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Example {@link SpringBootApplication} used with {@link DataNeo4jTest} tests. + * + * @author Eddú Meléndez + */ +@SpringBootApplication +public class ExampleNeo4jApplication { + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java new file mode 100644 index 0000000000..7c8b464dd1 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.springframework.data.neo4j.repository.GraphRepository; + +/** + * Example repository used with {@link DataNeo4jTest} tests. + * + * @author Eddú Meléndez + */ +public interface ExampleRepository extends GraphRepository { +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java new file mode 100644 index 0000000000..c7e2e7ee61 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.test.autoconfigure.data.neo4j; + +import org.neo4j.ogm.session.Session; + +import org.springframework.stereotype.Service; + +/** + * Example service used with {@link DataNeo4jTest} tests. + * + * @author Eddú Meléndez + */ +@Service +public class ExampleService { + + private final Session session; + + public ExampleService(Session session) { + this.session = session; + } + + public boolean hasNode(Class clazz) { + return this.session.countEntitiesOfType(clazz) == 1; + } +} diff --git a/spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java b/spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java new file mode 100644 index 0000000000..0c47a73874 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java @@ -0,0 +1,111 @@ +/* + * Copyright 2012-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. + * 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.springframework.boot.neo4j; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assume; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.neo4j.ogm.config.Configuration; +import org.neo4j.ogm.config.DriverConfiguration; +import org.neo4j.ogm.session.SessionFactory; + +/** + * {@link TestRule} for working with an optional Neo4j server. + * + * @author Eddú Meléndez + */ +public class Neo4jTestServer implements TestRule { + + private static final Log logger = LogFactory.getLog(Neo4jTestServer.class); + + private SessionFactory sessionFactory; + + private String[] packages; + + public Neo4jTestServer(String[] packages) { + this.packages = packages; + } + + @Override + public Statement apply(Statement base, Description description) { + try { + this.sessionFactory = createSessionFactory(); + return new Neo4jStatement(base, this.sessionFactory); + } + catch (Exception ex) { + logger.error("No Neo4j server available", ex); + return new SkipStatement(); + } + } + + private SessionFactory createSessionFactory() { + Configuration configuration = new Configuration(); + DriverConfiguration driverConfiguration = configuration.driverConfiguration(); + driverConfiguration.setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver"); + driverConfiguration.setURI("http://localhost:7474"); + + SessionFactory sessionFactory = new SessionFactory(configuration, this.packages); + testConnection(sessionFactory); + return sessionFactory; + } + + private void testConnection(SessionFactory sessionFactory) { + sessionFactory.openSession().beginTransaction().close(); + } + + private static class Neo4jStatement extends Statement { + + private final Statement base; + + private final SessionFactory sessionFactory; + + Neo4jStatement(Statement base, SessionFactory sessionFactory) { + this.base = base; + this.sessionFactory = sessionFactory; + } + + @Override + public void evaluate() throws Throwable { + try { + this.base.evaluate(); + } + finally { + try { + this.sessionFactory.close(); + } + catch (Exception ex) { + logger.warn("Exception while trying to cleanup neo4j resource", ex); + } + } + } + + } + + private static class SkipStatement extends Statement { + + @Override + public void evaluate() throws Throwable { + Assume.assumeTrue("Skipping test due to Neo4j SessionFactory" + + " not being available", false); + } + + } + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java b/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java new file mode 100644 index 0000000000..15ccefe4ae --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + * 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. + */ + +/** + * Neo4j support classes + */ +package org.springframework.boot.neo4j; From b08016f15afe5dab9fc3678629e0a3f08544680f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 2 Apr 2017 10:27:59 +0200 Subject: [PATCH 2/2] Polish "Add @DataNeo4jTest" contribution Closes gh-8618 --- .../main/asciidoc/spring-boot-features.adoc | 53 +++++++++++++++++++ spring-boot-test-autoconfigure/pom.xml | 6 --- .../data/neo4j/DataNeo4jTest.java | 4 +- .../neo4j/DataNeo4jTypeExcludeFilter.java | 1 - .../neo4j/DataNeo4jTestIntegrationTests.java | 11 ++-- ...TestWithIncludeFilterIntegrationTests.java | 1 - .../data/neo4j/ExampleGraph.java | 1 + .../data/neo4j/ExampleRepository.java | 4 +- .../data/neo4j/ExampleService.java | 1 + .../data}/neo4j/Neo4jTestServer.java | 18 ++++--- .../boot/neo4j/package-info.java | 20 ------- 11 files changed, 76 insertions(+), 44 deletions(-) rename {spring-boot/src/test/java/org/springframework/boot => spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data}/neo4j/Neo4jTestServer.java (86%) delete mode 100644 spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 4a82c87b48..5bf0cf63ed 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -5710,6 +5710,59 @@ A list of the auto-configuration that is enabled by `@DataMongoTest` can be +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test]] +==== Auto-configured Data Neo4j tests +`@DataNeo4jTest` can be used if you want to test Neo4j applications. By default, it will +use an in-memory embedded Neo4j (if the embedded driver is available), scan for +`@NodeEntity` classes and configure Spring Data Neo4j repositories. Regular `@Component` +beans will not be loaded into the `ApplicationContext`: + +[source,java,indent=0] +---- + import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; + import org.springframework.test.context.junit4.SpringRunner; + + @RunWith(SpringRunner.class) + @DataNeo4jTest + public class ExampleDataNeo4jTests { + + @Autowired + private YourRepository repository; + + // + } +---- + +Data Neo4j tests are transactional and rollback at the end of each test by default, +see the {spring-reference}#testcontext-tx-enabling-transactions[relevant section] in the +Spring Reference Documentation for more details. If that's not what you want, you can +disable transaction management for a test or for the whole class as follows: + +[source,java,indent=0] +---- + import org.junit.Test; + import org.junit.runner.RunWith; + import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; + import org.springframework.test.context.junit4.SpringRunner; + import org.springframework.transaction.annotation.Propagation; + import org.springframework.transaction.annotation.Transactional; + + @RunWith(SpringRunner.class) + @DataNeo4jTest + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public class ExampleNonTransactionalTests { + + } +---- + + +A list of the auto-configuration that is enabled by `@DataNeo4jTest` can be +<>. + + + [[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-client]] ==== Auto-configured REST clients The `@RestClientTest` annotation can be used if you want to test REST clients. By default diff --git a/spring-boot-test-autoconfigure/pom.xml b/spring-boot-test-autoconfigure/pom.xml index 7c51013c0b..d65d49ced9 100644 --- a/spring-boot-test-autoconfigure/pom.xml +++ b/spring-boot-test-autoconfigure/pom.xml @@ -217,11 +217,5 @@ de.flapdoodle.embed.mongo test - - org.springframework.boot - spring-boot - test-jar - test - diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java index 37650a922b..81ebe31308 100644 --- a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTest.java @@ -43,9 +43,11 @@ import org.springframework.transaction.annotation.Transactional; * configuration relevant to Neo4j tests. *

* By default, tests annotated with {@code @DataNeo4jTest} will use an embedded in-memory - * Neo4j process (if available). + * Neo4j process (if available). They will also be transactional with the usual + * test-related semantics (i.e. rollback by default). * * @author Eddú Meléndez + * @author Stephane Nicoll * @since 2.0.0 */ @Target(ElementType.TYPE) diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java index a19ca74bd5..5b0ee1cf7f 100644 --- a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilter.java @@ -28,7 +28,6 @@ import org.springframework.core.annotation.AnnotatedElementUtils; * {@link TypeExcludeFilter} for {@link DataNeo4jTest @DataNeo4jTest}. * * @author Eddú Meléndez - * @since 2.0.0 */ class DataNeo4jTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter { diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java index 6941fcc7ff..5883fcb8b3 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java @@ -24,16 +24,16 @@ import org.neo4j.ogm.session.Session; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.neo4j.Neo4jTestServer; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * Sample test for {@link DataNeo4jTest @DataNeo4jTest} + * Integration test for {@link DataNeo4jTest}. * * @author Eddú Meléndez + * @author Stephane Nicoll */ @RunWith(SpringRunner.class) @DataNeo4jTest @@ -41,7 +41,7 @@ public class DataNeo4jTestIntegrationTests { @Rule public Neo4jTestServer server = new Neo4jTestServer( - new String[]{"org.springframework.boot.test.autoconfigure.data.neo4j"}); + new String[] { "org.springframework.boot.test.autoconfigure.data.neo4j" }); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -59,8 +59,9 @@ public class DataNeo4jTestIntegrationTests { public void testRepository() { ExampleGraph exampleGraph = new ExampleGraph(); exampleGraph.setDescription("Look, new @DataNeo4jTest!"); - exampleGraph = this.exampleRepository.save(exampleGraph); - assertThat(exampleGraph.getId()).isNotNull(); + assertThat(exampleGraph.getId()).isNull(); + ExampleGraph savedGraph = this.exampleRepository.save(exampleGraph); + assertThat(savedGraph.getId()).isNotNull(); assertThat(this.session.countEntitiesOfType(ExampleGraph.class)).isEqualTo(1); } diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java index 4851a422c1..d0ab9e750b 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java @@ -21,7 +21,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.neo4j.Neo4jTestServer; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Service; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java index 43753d8067..55382d540a 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java @@ -49,4 +49,5 @@ public class ExampleGraph { public void setDescription(String description) { this.description = description; } + } diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java index 7c8b464dd1..bf3fb05b26 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleRepository.java @@ -16,12 +16,12 @@ package org.springframework.boot.test.autoconfigure.data.neo4j; -import org.springframework.data.neo4j.repository.GraphRepository; +import org.springframework.data.neo4j.repository.Neo4jRepository; /** * Example repository used with {@link DataNeo4jTest} tests. * * @author Eddú Meléndez */ -public interface ExampleRepository extends GraphRepository { +public interface ExampleRepository extends Neo4jRepository { } diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java index c7e2e7ee61..4472f1da69 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleService.java @@ -37,4 +37,5 @@ public class ExampleService { public boolean hasNode(Class clazz) { return this.session.countEntitiesOfType(clazz) == 1; } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/Neo4jTestServer.java similarity index 86% rename from spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java rename to spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/Neo4jTestServer.java index 0c47a73874..9f2636a735 100644 --- a/spring-boot/src/test/java/org/springframework/boot/neo4j/Neo4jTestServer.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/Neo4jTestServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.neo4j; +package org.springframework.boot.test.autoconfigure.data.neo4j; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -23,13 +23,14 @@ import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.neo4j.ogm.config.Configuration; -import org.neo4j.ogm.config.DriverConfiguration; import org.neo4j.ogm.session.SessionFactory; /** - * {@link TestRule} for working with an optional Neo4j server. + * {@link TestRule} for working with an optional Neo4j server running on localhost. Make + * sure to disable authentication if you haven't done so already. * * @author Eddú Meléndez + * @author Stephane Nicoll */ public class Neo4jTestServer implements TestRule { @@ -55,12 +56,13 @@ public class Neo4jTestServer implements TestRule { } } - private SessionFactory createSessionFactory() { - Configuration configuration = new Configuration(); - DriverConfiguration driverConfiguration = configuration.driverConfiguration(); - driverConfiguration.setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver"); - driverConfiguration.setURI("http://localhost:7474"); + public SessionFactory getSessionFactory() { + return this.sessionFactory; + } + private SessionFactory createSessionFactory() { + Configuration configuration = new Configuration.Builder() + .uri("bolt://localhost:7687").build(); SessionFactory sessionFactory = new SessionFactory(configuration, this.packages); testConnection(sessionFactory); return sessionFactory; diff --git a/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java b/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java deleted file mode 100644 index 15ccefe4ae..0000000000 --- a/spring-boot/src/test/java/org/springframework/boot/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - * 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. - */ - -/** - * Neo4j support classes - */ -package org.springframework.boot.neo4j;