1

I have some integration tests that are supposed to mock out one of many beans in my system. To do this, I have a @Configuration that looks like this:

@Configuration
public class MockContext {
    @Primary
    @Bean
    public RealBean realBean() {
        return new MockBean();
    }
}

I noticed that this method gets used if RealBean is a java class without @Component. But if RealBean is a @Component, I have to change this context method to look like this:

@Configuration
public class MockContext {
    @Primary
    @Bean
    public RealBean getRealBean() {
        return new MockBean();
    }
}

Can anyone explain why I need to change this method name and where I can find all these rules? It takes a very long time to troubleshoot these "why isn't my MockContext working correctly?" issues.

FWIW, here's how I'm using this context in a test:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RealContext.class, MockContext.class})
@WebAppConfiguration
public abstract class AbstractIntegrationTest {

And my integration test will extend this class. I am using Spring Boot 1.2.4.RELEASE

luboskrnac
  • 23,973
  • 10
  • 81
  • 92
Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356

1 Answers1

2

You can have various beans registered with same type. But they need to have different names.

If you use @Bean annotation without name attribute, name of the bean is extracted from method name (in your case realBean/getRealBean).

When you use @Component annotation without attribute (which specifies bean name), name of the bean is extracted from method name where first letter is lowercased.

So with your first case, you get a name clash. You can't have two beans named realBean.

Your second example is without clash because bean annotated by @Component has name realBean and second bean registered via @Bean has name getRealBean.

@Primary annotation helps Spring choose which bean to pick if there are two of the same type and you inject by type. When you inject by name (usage of @Qualifier annotation), you can inject also secondary instance.

luboskrnac
  • 23,973
  • 10
  • 81
  • 92