Skip to content

Commit

Permalink
Refine assertions on exception messages
Browse files Browse the repository at this point in the history
  • Loading branch information
snicoll committed Jun 14, 2022
1 parent b0f5fb5 commit b536b20
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -46,8 +46,8 @@ void runShouldCreateIndicator() {
@Test
void thresholdMustBePositive() {
this.contextRunner.withPropertyValues("management.health.diskspace.threshold=-10MB")
.run((context) -> assertThat(context).hasFailed().getFailure()
.hasMessageContaining("Failed to bind properties under 'management.health.diskspace'"));
.run((context) -> assertThat(context).hasFailed().getFailure().rootCause()
.hasMessage("threshold must be greater than or equal to 0"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ void customCacheResolverCanBeDefined() {
void notSupportedCachingMode() {
this.contextRunner.withUserConfiguration(DefaultCacheConfiguration.class)
.withPropertyValues("spring.cache.type=foobar")
.run((context) -> assertThat(context).getFailure().isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Failed to bind properties under 'spring.cache.type'"));
.run((context) -> assertThat(context).getFailure().isInstanceOf(BeanCreationException.class).rootCause()
.hasMessageContaining("No enum constant").hasMessageContaining("foobar"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindException;
import org.springframework.boot.context.properties.bind.BindException;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
Expand Down Expand Up @@ -75,7 +77,9 @@ void customPathMustBeginWithASlash() {
this.contextRunner.withPropertyValues("spring.h2.console.enabled=true", "spring.h2.console.path=custom")
.run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class)
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class).cause()
.isInstanceOf(ConfigurationPropertiesBindException.class).cause()
.isInstanceOf(BindException.class)
.hasMessageContaining("Failed to bind properties under 'spring.h2.console'");
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -48,10 +48,8 @@ class SessionAutoConfigurationIntegrationTests extends AbstractSessionAutoConfig
void severalCandidatesWithNoSessionStore() {
this.contextRunner.withUserConfiguration(HazelcastConfiguration.class).run((context) -> {
assertThat(context).hasFailed();
assertThat(context).getFailure().hasRootCauseInstanceOf(NonUniqueSessionRepositoryException.class);
assertThat(context).getFailure()
.hasMessageContaining("Multiple session repository candidates are available");
assertThat(context).getFailure()
assertThat(context).getFailure().rootCause().isInstanceOf(NonUniqueSessionRepositoryException.class)
.hasMessageContaining("Multiple session repository candidates are available")
.hasMessageContaining("set the 'spring.session.store-type' property accordingly");
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
void contextFailsIfMultipleStoresAreAvailable() {
this.contextRunner.run((context) -> {
assertThat(context).hasFailed();
assertThat(context).getFailure().hasRootCauseInstanceOf(NonUniqueSessionRepositoryException.class);
assertThat(context).getFailure()
assertThat(context).getFailure().rootCause().isInstanceOf(NonUniqueSessionRepositoryException.class)
.hasMessageContaining("Multiple session repository candidates are available");
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void createFromConfigClass() {
void missingHttpHandler() {
this.contextRunner.withUserConfiguration(MockWebServerConfiguration.class)
.run((context) -> assertThat(context.getStartupFailure())
.isInstanceOf(ApplicationContextException.class)
.isInstanceOf(ApplicationContextException.class).rootCause()
.hasMessageContaining("missing HttpHandler bean"));
}

Expand All @@ -93,7 +93,7 @@ void multipleHttpHandler() {
.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class,
TooManyHttpHandlers.class)
.run((context) -> assertThat(context.getStartupFailure())
.isInstanceOf(ApplicationContextException.class)
.isInstanceOf(ApplicationContextException.class).rootCause()
.hasMessageContaining("multiple HttpHandler beans : httpHandler,additionalHttpHandler"));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -51,8 +51,8 @@ void defaultConfiguration() {
@Test
void customPathMustBeginWithASlash() {
this.contextRunner.withPropertyValues("spring.webservices.path=invalid")
.run((context) -> assertThat(context).getFailure().isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Failed to bind properties under 'spring.webservices'"));
.run((context) -> assertThat(context).getFailure().isInstanceOf(BeanCreationException.class).rootCause()
.hasMessageContaining("Path must start with '/'"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -40,8 +40,7 @@ void createFromBeanHasDetails() {
new IllegalStateException());
assertThat(exception.getMessage()).isEqualTo("Error creating bean with name 'example': "
+ "Could not bind properties to 'ConfigurationPropertiesBindExceptionTests.Example' : "
+ "prefix=, ignoreInvalidFields=false, ignoreUnknownFields=true; "
+ "nested exception is java.lang.IllegalStateException");
+ "prefix=, ignoreInvalidFields=false, ignoreUnknownFields=true");
assertThat(exception.getBeanType()).isEqualTo(Example.class);
assertThat(exception.getBeanName()).isEqualTo("example");
assertThat(exception.getAnnotation()).isInstanceOf(ConfigurationProperties.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ void loadWhenFailsShouldIncludeAnnotationDetails() {
.isThrownBy(() -> load(IgnoreUnknownFieldsFalseConfiguration.class, "name=foo", "bar=baz"))
.withMessageContaining("Could not bind properties to "
+ "'ConfigurationPropertiesTests.IgnoreUnknownFieldsFalseProperties' : "
+ "prefix=, ignoreInvalidFields=false, ignoreUnknownFields=false;");
+ "prefix=, ignoreInvalidFields=false, ignoreUnknownFields=false");
}

@Test
Expand Down Expand Up @@ -810,8 +810,8 @@ void loadWhenConfigurationPropertiesContainsMapWithPositiveAndNegativeIntegerKey
@Test
void loadWhenConfigurationPropertiesInjectsAnotherBeanShouldNotFail() {
assertThatExceptionOfType(ConfigurationPropertiesBindException.class)
.isThrownBy(() -> load(OtherInjectPropertiesConfiguration.class))
.withMessageContaining(OtherInjectedProperties.class.getName())
.isThrownBy(() -> load(OtherInjectPropertiesConfiguration.class)).havingCause()
.isInstanceOf(BindException.class).withMessageContaining(OtherInjectedProperties.class.getName())
.withMessageContaining("Failed to bind properties under 'test'");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -53,8 +53,8 @@ void convertWhenFailsWithIOExceptionThrowsException(ConversionService conversion
InputStreamSource source = mock(InputStreamSource.class);
given(source.getInputStream()).willThrow(IOException.class);
assertThatExceptionOfType(ConversionFailedException.class)
.isThrownBy(() -> conversionService.convert(source, byte[].class))
.withCauseExactlyInstanceOf(IllegalStateException.class)
.isThrownBy(() -> conversionService.convert(source, byte[].class)).havingCause()
.isInstanceOf(IllegalStateException.class)
.withMessageContaining("Unable to read from input stream source");
}

Expand All @@ -66,9 +66,8 @@ void convertWhenFailsWithIOExceptionFromOriginProviderThrowsException(Conversion
given(source.getInputStream()).willThrow(IOException.class);
given(((OriginProvider) source).getOrigin()).willReturn(origin);
assertThatExceptionOfType(ConversionFailedException.class)
.isThrownBy(() -> conversionService.convert(source, byte[].class))
.withCauseExactlyInstanceOf(IllegalStateException.class)
.withMessageContaining("Unable to read from mylocation");
.isThrownBy(() -> conversionService.convert(source, byte[].class)).havingCause()
.isInstanceOf(IllegalStateException.class).withMessageContaining("Unable to read from mylocation");
}

@ConversionServiceTest
Expand All @@ -78,9 +77,8 @@ void convertWhenFailsWithIOExceptionFromResourceThrowsException(ConversionServic
given(source.getInputStream()).willThrow(IOException.class);
given(source.getDescription()).willReturn("myresource");
assertThatExceptionOfType(ConversionFailedException.class)
.isThrownBy(() -> conversionService.convert(source, byte[].class))
.withCauseExactlyInstanceOf(IllegalStateException.class)
.withMessageContaining("Unable to read from myresource");
.isThrownBy(() -> conversionService.convert(source, byte[].class)).havingCause()
.isInstanceOf(IllegalStateException.class).withMessageContaining("Unable to read from myresource");
}

static Stream<? extends Arguments> conversionServices() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -88,6 +88,7 @@ void convertWhenSimpleWithoutSuffixButWithAnnotationShouldReturnDataSize(Convers
@ConversionServiceTest
void convertWhenBadFormatShouldThrowException(ConversionService conversionService) {
assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() -> convert(conversionService, "10WB"))
.havingCause().isInstanceOf(IllegalArgumentException.class)
.withMessageContaining("'10WB' is not a valid data size");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand Down Expand Up @@ -121,7 +121,7 @@ void convertWhenSimpleWithoutSuffixButWithAnnotationShouldReturnDuration(Convers
@ConversionServiceTest
void convertWhenBadFormatShouldThrowException(ConversionService conversionService) {
assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() -> convert(conversionService, "10foo"))
.withMessageContaining("'10foo' is not a valid duration");
.havingRootCause().withMessageContaining("'10foo' is not a valid duration");
}

@ConversionServiceTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@ void cleanUp() {
@Test
void whenThereIsNoWebServerFactoryBeanThenContextRefreshWillFail() {
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining(
.havingRootCause().withMessageContaining(
"Unable to start ReactiveWebServerApplicationContext due to missing ReactiveWebServerFactory bean");
}

@Test
void whenThereIsNoHttpHandlerBeanThenContextRefreshWillFail() {
addWebServerFactoryBean();
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.havingRootCause()
.withMessageContaining("Unable to start ReactiveWebApplicationContext due to missing HttpHandler bean");
}

Expand All @@ -76,7 +77,7 @@ void whenThereAreMultipleWebServerFactoryBeansThenContextRefreshWillFail() {
addWebServerFactoryBean();
addWebServerFactoryBean("anotherWebServerFactory");
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining(
.havingRootCause().withMessageContaining(
"Unable to start ReactiveWebApplicationContext due to multiple ReactiveWebServerFactory beans");
}

Expand All @@ -86,7 +87,7 @@ void whenThereAreMultipleHttpHandlerBeansThenContextRefreshWillFail() {
addHttpHandlerBean("httpHandler1");
addHttpHandlerBean("httpHandler2");
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining(
.havingRootCause().withMessageContaining(
"Unable to start ReactiveWebApplicationContext due to multiple HttpHandler beans");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ void servletContextAwareBeansAreInjected() {
@Test
void missingServletWebServerFactory() {
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.havingRootCause()
.withMessageContaining("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean");
}
Expand All @@ -214,7 +215,7 @@ void tooManyWebServerFactories() {
this.context.registerBeanDefinition("webServerFactory2",
new RootBeanDefinition(MockServletWebServerFactory.class));
assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining("Unable to start ServletWebServerApplicationContext due to "
.havingRootCause().withMessageContaining("Unable to start ServletWebServerApplicationContext due to "
+ "multiple ServletWebServerFactory beans");

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2022 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.
Expand All @@ -21,6 +21,7 @@

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.bind.validation.BindValidationException;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

Expand Down Expand Up @@ -56,15 +57,15 @@ void bindValidProperties() {
void bindInvalidHost() {
this.context.register(SamplePropertyValidationApplication.class);
TestPropertyValues.of("sample.host:xxxxxx", "sample.port:9090").applyTo(this.context);
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining("Failed to bind properties under 'sample'");
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh).havingRootCause()
.isInstanceOf(BindValidationException.class);
}

@Test
void bindNullHost() {
this.context.register(SamplePropertyValidationApplication.class);
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> this.context.refresh())
.withMessageContaining("Failed to bind properties under 'sample'");
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh).havingRootCause()
.isInstanceOf(BindValidationException.class);
}

@Test
Expand Down

0 comments on commit b536b20

Please sign in to comment.