Search code examples
javaspringspring-bootjavabeans

How to Exclude Configuration from Spring IT?


It seems this is a very straightforward question, especially since it already works sometimes in my application. I have no idea why that is, so if I've missed some important information, just tell me.

First of all, I have a test case:

package org.acme.webportal.service;

@SpringBootTest(classes = {TestApplication.class})
public class ServiceImplTest

}

This test has an application defined like this:

package org.acme.webportal;

@SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class})
@PropertySource(value = {"classpath:application.properties"})
@EnableConfigurationProperties
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
    value = {DConfiguration.class})})
public class TestApplication extends SpringBootServletInitializer {

  public static void main(String[] args) {
    SpringApplication.run(TestApplication.class, args);
  }
}

This test excludes a configuration from the test which looks like this:

package org.acme.webportal.security.ds;

@Configuration
public class DConfiguration {

}

Which, as far as I can tell, works perfectly. Now I want to exclude this configuration:

package org.acme.webportal.service.jobmanager.logic;

@Configuration
public class JConfiguration {

}

How do I exclude this?

I tried:


// just as the working exclusion above-> does not work
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {JConfiguration.class})})

// add it to the working excludeFilter -> does not work for JConfiguration, only for DConfiguration
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {DConfiguration.class, JConfiguration.class})})

// add it to the working excludeFilters -> does not work for JConfiguration, only for DConfiguration
@ComponentScan(excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {DConfiguration.class}),
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {JConfiguration.class})
})

// maybe as a pattern? the pattern might be wrong, the config is still present
@ComponentScan.Filter(type = FilterType.REGEX, pattern = {"org\\.acme\\.webportal\\.service\\.jobmanager\\.logic.*"})

// does not work because it's no auto configuration
@SpringBootApplication(exclude = {JConfiguration.class})

// does not work because it's no auto configuration
@EnableAutoConfiguration(exclude = {JConfiguration.class})

The reason I know this doesn't work is because this message keeps popping up:

The bean 'mapUploadJobLauncher', defined in class path resource [org/acme/webportal/service/jobmanager/logic/JConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/acme/webportal/service/jobmanager/logic/MockJConfiguration.class] and overriding is disabled.

(Which means that the mock config I defined especially for the tests, is in conflict with the production config, which I really want to exclude.)

I know Spring Boot is really fickle with the packages, but I have no idea at all what I'm doing wrong here. How do I exclude the configuration from the IT?


Solution

  • So the problem in this case is that Applications in close vicinity import each other, but not in the way it would make sense.

    There was a second application without the exclude, and so Spring figured it could just add the excluded class anyways. I wanted to have feature / package based Spring test application, this seems not to be possible. I merged them into one big application and now exclusion works normally.