Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering test bean with same name in Spring Framework 5.1 [duplicate]

I'm having following config in my production files:

@Configuration
internal class Config {

  @Bean
  fun clock() = Clock.systemUTC()
}

In tests:

@Configuration
class ClockTestConfiguration {

  @Bean
  fun clock() = SetableClock()
}

My test annotations:

@SpringBootTest(
  webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
  classes = [
    MyApplication::class,
    ClockTestConfiguration::class
  ]
)
class MyTest {
...

When I was using Spring Boot 2.0.5.RELEASE it worked like a charm. After upgrading to 2.1.0.RELEASE it fails during bean registration.

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'clock' defined in com.foo.clock.ClockTestConfiguration: 
Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=clockTestConfiguration; factoryMethodName=clock; initMethodName=null; destroyMethodName=(inferred); 
defined in com.foo.clock.ClockTestConfiguration] for bean 'clock': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=config; factoryMethodName=clock; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/foo/clock/Config.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)

Is there a clean way to override such bean?

like image 537
pixel Avatar asked Nov 20 '18 21:11

pixel


People also ask

Can we have two beans with same name in Spring?

Spring beans are identified by their names within an ApplicationContext. Therefore, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext that has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.

Can we have two beans with same class name?

If you define two beans of same class, without different bean id or qualifiers ( identifier) , Spring container will not be able to understand which bean to be loaded , if you try to access the bean by passing the classname and you will get NoUniqueBeanDefinitionException as there are two qualifying TestBean.

How is Spring bean uniquely identified?

This attribute specifies the bean identifier uniquely. In XMLbased configuration metadata, you use the id and/or name attributes to specify the bean identifier(s). This attribute specifies the scope of the objects created from a particular bean definition and it will be discussed in bean scopes chapter.


1 Answers

You could use the properties attribute of @SpringBootTest to set spring.main.allow-bean-definition-overriding=true.

like image 165
Andy Wilkinson Avatar answered Nov 05 '22 19:11

Andy Wilkinson