Java Spring Boot Test: How to exclude java configuration class from test context

74,791

Solution 1

Typically you would use Spring profiles to either include or exclude Spring beans, depending on which profile is active. In your situation you could define a production profile, which could be enabled by default; and a test profile. In your production config class you would specify the production profile:

@Configuration
@PropertySource("classpath:otp.properties")
@Profile({ "production" })
public class OTPConfig {
}

The test config class would specify the test profile:

@TestConfiguration
@Import({ TestDataSourceConfig.class, TestMailConfiguration.class,    TestOTPConfig.class })
@TestPropertySource("classpath:amc-test.properties")
@Profile({ "test" })
public class TestAMCApplicationConfig extends AMCApplicationConfig {
}

Then, in your test class you should be able to say which profiles are active:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestAMCApplicationConfig.class)
@ActiveProfiles({ "test" })
public class AuthUserServiceTest {
  ....
}

When you run your project in production you would include "production" as a default active profile, by setting an environment variable:

JAVA_OPTS="-Dspring.profiles.active=production"

Of course your production startup script might use something else besides JAVA_OPTS to set the Java environment variables, but somehow you should set spring.profiles.active.

Solution 2

You can also use @ConditionalOnProperty like below:

@ConditionalOnProperty(value="otpConfig", havingValue="production")
@Configuration
@PropertySource("classpath:otp.properties")
public class OTPConfig { }

and for tests:

@ConditionalOnProperty(value="otpConfig", havingValue="test")
@Configuration
@PropertySource("classpath:otp-test.properties")
public class TestOTPConfig { }

Then specify in your main/resources/config/application.yml

otpConfig: production

and in your test/resources/config/application.yml

otpConfig: test

Solution 3

You can also just mock the configuration you don't need. For example:

@MockBean
private AnyConfiguration conf;

Put it into your test class. This should help to avoid that the real AnyConfiguration is being loaded.

Solution 4

Additionally, for excluding auto configuration:

@EnableAutoConfiguration(exclude=CassandraDataAutoConfiguration.class)
public class // ...
Share:
74,791
Admin
Author by

Admin

Updated on March 16, 2021

Comments

  • Admin
    Admin about 3 years

    I have a Java web app with spring boot

    When run test I need to exclude some Java config files:

    Test config (need to include when test run):

    @TestConfiguration
    @PropertySource("classpath:otp-test.properties")
    public class TestOTPConfig { }
    

    Production config (need to exclude when test run):

     @Configuration
     @PropertySource("classpath:otp.properties")
     public class OTPConfig { }
    

    Test class (with explicit config class):

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = TestAMCApplicationConfig.class)
    public class AuthUserServiceTest { .... }
    

    Test config:

    @TestConfiguration
    @Import({ TestDataSourceConfig.class, TestMailConfiguration.class, TestOTPConfig.class })
    @TestPropertySource("classpath:amc-test.properties")
    public class TestAMCApplicationConfig extends AMCApplicationConfig { }
    

    Also have class:

    @SpringBootApplication
    public class AMCApplication { }
    

    When test is running OTPConfig used, but I need TestOTPConfig...

    How can I do it?