Description
It is convenient that Spring Boot autoconfiguration supports creating a RestClient.Builder. However, it is not clear how to best use the RestClient.Builder
when testing.
Boot provides @RestClientTest
which makes it easier to test when using RestTemplateBuilder
. However, at the moment (Spring Boot 3.2.0-M1) using RestClient.Builder
with @RestClientTest
produces the following error:
Failed to load ApplicationContext for [MergedContextConfiguration@abff8b7 testClass = example.RepositoryServiceTests, locations = [], classes = [example.Application], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.client.RestClientTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@27d4a09, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@9be1041, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@95d784df, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@6436a7db, [ImportsContextCustomizer@6d7cada5 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.test.autoconfigure.web.client.WebClientRestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@16c63f5, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@b1712f3, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@f946572c], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@abff8b7 testClass = example.RepositoryServiceTests, locations = [], classes = [example.Application], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.client.RestClientTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@27d4a09, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@9be1041, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@95d784df, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@6436a7db, [ImportsContextCustomizer@6d7cada5 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.test.autoconfigure.web.client.WebClientRestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@16c63f5, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@b1712f3, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@f946572c], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'repositoryService' defined in class path resource [example/RepositoryServiceConfiguration.class]: Unsatisfied dependency expressed through method 'repositoryService' parameter 0: No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:801)
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
If I try and @ImportAutoConfiguration(RestClientAutoConfiguration.class)
I get the following error:
Unable to use auto-configured MockRestServiceServer since MockServerRestTemplateCustomizer has not been bound to a RestTemplate
java.lang.IllegalStateException: Unable to use auto-configured MockRestServiceServer since MockServerRestTemplateCustomizer has not been bound to a RestTemplate
at org.springframework.util.Assert.state(Assert.java:76)
at org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration$DeferredRequestExpectationManager.getDelegate(MockRestServiceServerAutoConfiguration.java:116)
at org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration$DeferredRequestExpectationManager.expectRequest(MockRestServiceServerAutoConfiguration.java:88)
at org.springframework.test.web.client.MockRestServiceServer.expect(MockRestServiceServer.java:108)
at org.springframework.test.web.client.MockRestServiceServer.expect(MockRestServiceServer.java:93)
at example.RepositoryServiceTests.getRepository(RepositoryServiceTests.java:26)
...
I am able to work around it by using RestClient.builder(RestTemplateBuilder.build())
instead of the RestClient.Builder
, but this seems to defeat the purpose of RestClient.Builder
being provided by Boot's autoconfiguration.
It would be nice if there was a way I can use the autoconfigured RestClient.Builder
in my tests.
You can find the last 3 commits in this branch demonstrate the various items I described https://github.com/rwinch/spring-security-sample/tree/boot-test-restclient