If one adds the spring-boot-admin-starter-client dependency to an app one cannot run the tests without configuring the admin-server "connection" as it results in the following Exception:
2015-08-03 13:31:55.694 ERROR 4600 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@91161c7] to prepare test instance [demo.AppTests@6fd02e5]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.boot.admin.client.CONFIGURATION_PROPERTIES': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.boot.autoconfigure.web.ServerProperties de.codecentric.boot.admin.config.AdminClientProperties.server; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.autoconfigure.web.ServerProperties] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 25 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.boot.autoconfigure.web.ServerProperties de.codecentric.boot.admin.config.AdminClientProperties.server; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.autoconfigure.web.ServerProperties] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 40 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.autoconfigure.web.ServerProperties] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 42 common frames omitted
It would be nice to be able to disable the admin starter client for tests.
Another option would be to declare the autowired dependencies to ServerProperties in de.codecentric.boot.admin.config.AdminClientProperties optional, e.g. via:
@Autowired(required=false)
private ServerProperties server;
If there is another prefered way to configure the tests to not cause the above exception it would be great to have an example for that in the spring-boot-admin-samples :)
Cheers,
Thomas
This is a bug in 1.2.2 and has been fixed in the master branch with https://github.com/codecentric/spring-boot-admin/commit/946f3bd63bb661fcffc670805a9cfb3998fb3277
Hi joshiste,
We have problem running our integrations tests, we setup our application to use the last version of spring boot admin as you said :
compile("de.codecentric:spring-boot-admin-starter-client:1.2.3")
but we still have the issue with the BeanCreationException.
Please assure u don't set the spring.boot.admin.url property in your tests
Hi joshiste,
Sorry for the delay, we do set the spring.boot.admin.url, we'll use another profile for tests. Thank you for you're help!
I had the same problem and I finally got my integration tests to run by adding the @WebIntegrationTest annotation.
Hope this helps
It helps adding the @WebIntegrationTest annotation, but integration tests became very slow. By adding the de.codecentric spring-boot-admin-starter-client, the time it take to run all tests multiplied ten-fold - and that is without adding any other tests, just by adding the packages and a couple properties (from 12-15 sec to 2m30s).
I wish for a disable-toggle while testing. It might be there, but cannot find it in the docs.
Why don't you just keep out the spring.boot.admin.url proprrty from your test-config? I think it would be the same effort as to add an additional property for disabling, or not?
Thanks, but I prefer using real values, properties and schemas for integration tests to ensure that the tests reflect production as close as possible. Too many projects suffer with differences between production and development where errors are not found before release.
I did find the correct properties to use in the value-section in WebIntegrationTest.
Using @WebIntegrationTest(value={"spring.boot.admin.url="}) disable attempt to register to server. Result is that it builds on 14-16 sec, so not as fast as it was, but well within acceptable build time :)
A spring.boot.admin.enabled property would still be nice and more intuitive than leaving spring.boot.admin.url empty.
PR welcome
Ok. Do you have an objection if I change
@ConditionalOnProperty("spring.boot.admin.url") to
@ConditionalOnProperty(
prefix = "spring.boot.admin.client",
name = {"enabled"},
matchIfMissing = true
)
The client would be enabled by default. But it would break backward compability.
Or do you want me to write a more complex SpringBootClientEnablerCondition which extends SpringBootCondition and checks both properties?
When possible the old behavior should be kept. So this would be this matrix:
| | enabled = false | enabled = true (default) |
| --- | --- | --- |
| url empty (default) | inactive | inactive |
| url set | inactive | active |
your change would activate the config although the url is unset...
I've reopened this as enhancment to be closed by your PR
Ok. I've already created a new issue.
duplicates #156
It looks fine to me.
Most helpful comment
I had the same problem and I finally got my integration tests to run by adding the @WebIntegrationTest annotation.
Hope this helps