0

I have Spring Boot 3.5 application:

@SpringBootApplication(
 scanBasePackages = [
 ...
 ]
)
@EnableConfigurationProperties(
 value = [
 ....
 MyProps::class,
 ]
)
class MyApplication
fun main(args: Array<String>) {
 val application = runApplication<DepositFlCoreApplication>(*args)
 val props = application.getBean(MyProps::class.java)
 println(props)
}
@ConfigurationProperties(prefix = "my.ttl")
data class MyProps(
 val prop1: Duration,
 val prop2: Duration,
)

I have in application.yaml:

my:
 ttl:
 prop1: 12h
 prop2: 14h

Application starts properly without any issue and I see that

 val props = application.getBean(MyProps::class.java)

reads correct result.

Now I try to implement test:

@SpringBootTest(
 classes = [MyProps::class]
)
@Tag("integration-test")
class MyTest {
 @SpykBean
 lateinit var myProps: MyProps
 @Test
 fun foo() {
 print(myProps)
 }
}

in src/test/resources/application.yaml I also have

my:
 ttl:
 prop1: 12h
 prop2: 14h

When I start test I see:

Error creating bean with name 'myProps': Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'java.time.Duration' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myProps': Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'java.time.Duration' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
 at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
 at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
 at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
 at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
 at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
 at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
 at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean0ドル(AbstractBeanFactory.java:339)
 at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
 at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
 at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222)
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188)
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123)
 at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
 at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
 at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
 at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
 at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
 at app//org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext3ドル(SpringBootContextLoader.java:144)
 at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
 at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
 at app//org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1462)
 at app//org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:563)
 at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:144)
 at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:110)
 at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
 at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
 at app//org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
 at app//org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:200)
 at app//org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:139)
 at app//org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
 at app//org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:159)
 at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
 at [email protected]/java.util.stream.ReferencePipeline3ドル1ドル.accept(ReferencePipeline.java:197)
 at [email protected]/java.util.stream.ReferencePipeline2ドル1ドル.accept(ReferencePipeline.java:179)
 at [email protected]/java.util.stream.ReferencePipeline3ドル1ドル.accept(ReferencePipeline.java:197)
 at [email protected]/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
 at [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
 at [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
 at [email protected]/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
 at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
 at [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
 at [email protected]/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
 at [email protected]/java.util.Optional.orElseGet(Optional.java:364)
 at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
 at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.time.Duration' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:2280)
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1703)
 at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628)
 at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
 at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
 ... 45 more

How to fix it ?

P.S. I tried to comminicate with AI but it didn't provide any clue

Update for M.Denium:

If I replace

@ConfigurationProperties(prefix = "my.ttl")
data class MyProps(
 val prop1: Duration,
 val prop2: Duration,
)

with

@ConfigurationProperties(prefix = "my.ttl")
class MyProps(
 lateinit var prop1: Duration,
 lateinit var prop2: Duration,
)

Everything is working

asked Aug 11, 2025 at 16:58
19
  • Do you know whether Spring knows how to convert the String "12h" to a Duration? Commented Aug 11, 2025 at 23:00
  • Remove the classes from the @SpringBootTest. YOu are now bootstrapping a test with only that class, which doesn't have any further config. Commented Aug 12, 2025 at 6:20
  • @M. Deinum It is artificial example. Actually I have a real spring context which require postgres. kafka etc. So if I remove classes - other context beans are not loaded Commented Aug 12, 2025 at 7:13
  • So this doesn't reflect what you are actually doing. The @SpringBootTest is for an integration test and should point to your application entry point. If you only point it to a subset of classes it probably will fail as there is no @SpringBootAPplication being detected and thus not all automatic features are present (which is what is displayed here as well). YOu just add a class however this doesn't enable the @EnableConfigurationProperties it just adds a class and doesn't do any binding etc. Commented Aug 12, 2025 at 7:22
  • Here it is even worse as it will be treated as a regular component, which requires beans for the constructor (which is what the error tells you). Commented Aug 12, 2025 at 7:25

1 Answer 1

0

You did not format your setting value properly.

See this answer for full explanation.

answered Aug 25, 2025 at 15:42
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.