From ffa6d6d6e0841c598ae55a54969fe60abd17c369 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 19 Jan 2017 16:13:49 +0100 Subject: [PATCH] Improve error message used in TestDatabaseAutoConfiguration By default, `@DataJpaTest` (and `@AutoConfigureTestDatabase`) attempt to replace any existing `DataSource` by an embedded one. Previously, if there is was no embedded database on the classpath, the exception message did not provide that context in the error message. This commit clarifies the error message to conduct `TestDatabaseAutoConfiguration` (that is replacing the existing `DataSource`). Closes gh-7797 --- .../jpa/TestDatabaseAutoConfiguration.java | 9 +- ...abaseAutoConfigurationNoEmbeddedTests.java | 106 ++++++++++++++++++ 2 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfigurationNoEmbeddedTests.java diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfiguration.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfiguration.java index 2f2e13df143..e50dc4f2f76 100644 --- a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfiguration.java +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -193,9 +193,10 @@ public class TestDatabaseAutoConfiguration { connection = EmbeddedDatabaseConnection.get(getClass().getClassLoader()); } Assert.state(connection != EmbeddedDatabaseConnection.NONE, - "Cannot determine embedded database for tests. If you want " - + "an embedded database please put a supported one " - + "on the classpath."); + "Failed to replace DataSource with an embedded database for tests. If " + + "you want an embedded database please put a supported one " + + "on the classpath or tune the replace attribute of " + + "@AutoconfigureTestDatabase."); return new EmbeddedDatabaseBuilder().generateUniqueName(true) .setType(connection.getType()).build(); } diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfigurationNoEmbeddedTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfigurationNoEmbeddedTests.java new file mode 100644 index 00000000000..925db0f0349 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestDatabaseAutoConfigurationNoEmbeddedTests.java @@ -0,0 +1,106 @@ +/* + * 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.orm.jpa; + +import javax.sql.DataSource; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.boot.testutil.ClassPathExclusions; +import org.springframework.boot.testutil.FilteredClassPathRunner; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Specific tests for {@link TestDatabaseAutoConfiguration} when no embedded database is + * available. + * + * @author Stephane Nicoll + */ +@RunWith(FilteredClassPathRunner.class) +@ClassPathExclusions({ "h2-*.jar", "hsqldb-*.jar", "derby-*.jar" }) +public class TestDatabaseAutoConfigurationNoEmbeddedTests { + + private ConfigurableApplicationContext context; + + @After + public void closeContext() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void applyAnyReplace() { + try { + load(ExistingDataSourceConfiguration.class); + } + catch (BeanCreationException ex) { + String message = ex.getMessage(); + assertThat(message).contains( + "Failed to replace DataSource with an embedded database for tests."); + assertThat(message).contains( + "If you want an embedded database please put a supported one on the " + + "classpath"); + assertThat(message).contains( + "or tune the replace attribute of @AutoconfigureTestDatabase."); + } + } + + @Test + public void applyNoReplace() { + load(ExistingDataSourceConfiguration.class, "spring.test.database.replace=NONE"); + assertThat(this.context.getBeansOfType(DataSource.class)).hasSize(1); + assertThat(this.context.getBean(DataSource.class)).isSameAs( + this.context.getBean("myCustomDataSource")); + } + + public void load(Class config, String... environment) { + this.context = doLoad(config, environment); + } + + public ConfigurableApplicationContext doLoad(Class config, String... environment) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + if (config != null) { + ctx.register(config); + } + ctx.register(TestDatabaseAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(ctx, environment); + ctx.refresh(); + return ctx; + } + + @Configuration + static class ExistingDataSourceConfiguration { + + @Bean + public DataSource myCustomDataSource() { + return mock(DataSource.class); + } + + } + +}