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
This commit is contained in:
Stephane Nicoll 2017-01-19 16:13:49 +01:00
parent 80a1e1ae64
commit ffa6d6d6e0
2 changed files with 111 additions and 4 deletions

View File

@ -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();
}

View File

@ -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);
}
}
}