Spring override bean of another module

963 Views Asked by At

In my multimodule project I have integration tests as seperate module. That tests have application jar added as dependency. Is it possible to override application bean definition from integration tests?

In application I have following Bean (standard java mail sender configuration)

@Configuration
public class MailConfiguration {

   @Bean
   public JavaMailSender javaMailService() {
      JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
      //standard mail configuration using properties
   }
}

Now all my integration tests extends BaseIntegrationTest that loads test configuration classess

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { AppTestConfiguration.class, MailTestConfiguration.class})
public class BaseIntegrationTest {

}

And finally in my MailTestConfiguration I define another JavaMailSender

@Primary
@Bean
@Profile(TestProfiles.MAIL_GREEN_SMTP)
public JavaMailSender javaMailService() {

    JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
    javaMailSender.setHost("localhost");
    javaMailSender.setPort(3025);

    return javaMailSender;
}

It is working when I run the tests from application itself. When I run the tests from another module the bean is not overriden.

I am aware that AppConfiguration class defined inside application cannot component scan the integration tests config classes so I also load AppTestConfiguration.

@Configuration
@ComponentScan(basePackages = {"..."})
public class AppTestConfiguration extends AppConfiguration {

}

How to make it work?

2

There are 2 best solutions below

0
On BEST ANSWER

Two things you should check:

  1. Is the right Spring profile enabled when you run the tests from another module?
  2. Is the given configuration in the scan path when you run the tests from another module?
0
On

Sure I messed up with profiles. In my BaseIntegrationTest I defined active profile based on configuration. I also printed which profile gets resolved there (correct profile name was printed)


    @BeforeClass
    public static void init() {
        System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, ProfileResolver.getActiveProfiles());
    }

After you convinced me that it should work I rechecked the config and found that I also added spring.profiles.active in properties. After deleting this config everything work as expected. The other way is to use AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME instead of AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME