17

I have a java configuration class providing fooBean directly and barBean by component scan.

@Configuration
@ComponentScan(basePackages = { "com.blah" })
public class Config {

    @Bean
    public FooBean fooBean {
        return new FooBean();
    }
}

and i want to reuse it in the test cases and i need to replace the beans with mocks:

@Configuration
@Import(Config.class)
public class TestConfig {

    @Bean
    public FooBean fooBean {
        return new FooBeanMock();
    }

    @Bean
    public BarBean barBean {
        return new BarBeanMock();
    }
}

(here it does not make much sense to reuse Config, but in real life i have 1000 Beans and i need to mock only a few)

Here fooBean gets overridden, but not barBean.

Skipping loading bean definition for %s: a definition for bean " + "'%s' already exists. This is likely due to an override in XML.

There is also an official issue for it: https://jira.springsource.org/browse/SPR-9682

does somebody knows any workaround to override a bean discovered by component scan?

taking into account that the bean is legacy code and can not be modified and there are NO setters for its dependencies (private attributes + @Resource).

mmoossen
  • 1,237
  • 3
  • 21
  • 32

2 Answers2

8

Try to skip unnecessary beans:

@ComponentScan(basePackages = { "com.blah" }, excludeFilters = @Filter({UnnecessaryBean1.class, UnnecessaryBean2.class}))
Maksym Demidas
  • 7,707
  • 1
  • 29
  • 36
  • i can not skip them in the main config. because i need the bean and i do not see any possibility to instantiate that bean otherwise because of "Taking into account that the bean is legacy code and can not be modified and there are NO setters for its dependencies (private attributes + @Resource).". On the test config that is importing the main config, it does not make any sense, since the comp scan from the imported main config will be executed anyhow. – mmoossen Apr 15 '13 at 07:24
  • 1
    May be you can split your main config into two parts: 1) component scan 2) everything else. And then import only the second one in your test config. So you will be ale override component scan settings for tests. – Maksym Demidas Apr 15 '13 at 10:13
-1

Yes you can override bean discovered by component scan. I do it this in test cases. I use XML configuration but I think with Java Configuration will be very similar.

spring.xml:

 <context:component-scan base-package="cz.backend"/>

MyBeanImpl.java

@Component("myBean")
public class MyBeanImpl implements MyBean {
   //Something
}

In test folder I have:

spring-test.xml:

<import resource="classpath:/spring.xml"/>
<bean id="myBean" class="cz.backend.MyBeanTestMock"/>

MyBeanTestMock.java:

public class MyBeanTestMock implements MyBean {
    //Something
}

Name of override bean must be same.

Saljack
  • 2,072
  • 21
  • 24