I am trying to override a Spring bean during a test declared in a test configuration with the use of @Primary. One declaration is in the src/main/java path, the other, the primary, is in src/test/java path.
However, Spring is intentionally replacing the primary bean with the the non-primary bean, the one I don't want to use for the test. If I simply comment out the production (src/main/java) configuration bean, it uses the primary test (src/main/test) bean in the test configuration as desired. (Clearly I can't comment out code every time I want to run a test.)
From the logs:
o.s.b.f.s.DefaultListableBeanFactory - Overriding bean definition for bean 'sqsConnectionFactory' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=true; factoryBeanName=testJmsConfiguration; factoryMethodName=sqsConnectionFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/foo/configuration/TestJmsConfiguration.class]]
with
[Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jmsConfiguration; factoryMethodName=sqsConnectionFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/foo/configuration/JmsConfiguration.class]]
Why is spring replacing a primary bean with a non-primary bean and how do I get Spring to use the bean specifically marked as the primary bean?
Edit: The src/main/java configuration:
@Configuration
public class JmsConfiguration {
... other bean declarations here ...
@Bean
public SQSConnectionFactory sqsConnectionFactory(Region region) throws JMSException {
return SQSConnectionFactory.builder()
.withRegion(region)
.build();
}
}
The test configuration:
@Configuration
public class TestJmsConfiguration {
@Bean(name="messageProducerMock")
public MessageProducer mockMessageProducer() {
return new MessageProducerMock();
}
... other bean declarations here ...
@Bean
@Primary
public SQSConnectionFactory sqsConnectionFactory(@Qualifier("messageProducerMock") MessageProducer messageProducerMock) throws JMSException {
... returning setup mock here
}
}
The class with the tests is annotated with:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles(profiles = {"test"})