user91604
user91604

Reputation: 113

How to exclude classes with @Configuration in @SpringBootApplication testing

I am using a dependent module called spring-cloud-aws. It has a @Configuration class as org.springframework.cloud.aws.messaging.config.annotation.SqsConfiguration In my SpringBoot JUnit test case the SqsConfiguration class is getting detected and Beans are getting initialized. I want to exclude this Configuration in class in my JUNit test case. How to achieve this ?

I tried using @ComponentScan it didn't work.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SQLTestConfig.class)
@ActiveProfiles("test")
public class BusinessManagerTest {

}

@TestConfiguration
@ComponentScan(basePackages = {"package1","package1"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = SqsConfiguration.class)})
@Profile("test")
class SQLTestConfig {   

    @Bean
    public SomeBean beans() {

        return new SomeBean();
    }



}

Loading this configuration class requires aws credentials to be available. I don't want to inject credentials for running a simple Bean test case.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMessageListenerContainer' defined in class path resource [org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class]: Invocation of init method failed; nested exception is com.amazonaws.services.sqs.model.AmazonSQSException: The security token included in the request is expired

Upvotes: 5

Views: 8978

Answers (3)

Paul
Paul

Reputation: 1150

Late to the party, but verified with SpringBoot 3.1.4 and Java 21:

  • create an empty mock of the offending bean, this will override the autoconfiguration of the original bean from your @Configuration class

Take note, I don't encourage this. But I'm also guilty of making it work this way in one of my testclasses.

@SpringBootTest
@ActiveProfiles("test") // non-necessary annotation
class ApplicationTests {

    @MockBean
    private YourCustomBean yourCustomBean;

    @Test
    void test_something_that_does_not_use_your_custom_bean() {
        // test your code here...
    }

}

Upvotes: 1

Isaac Philip
Isaac Philip

Reputation: 566

So to disable the auto-loading of all Beans for a Test, the test class can explicitly mention the dependencies required. This can be done using ContextConfiguration annotation. eg,

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {EmployeeService.class})
public class EmployeeLeavesTest { 

   @Autowired
   private EmployeeService employeeService;

}

In this eg, only EmployeeService class will be available and other beans will not be loaded.

Upvotes: 0

Oleksii Zghurskyi
Oleksii Zghurskyi

Reputation: 4365

There are multiple ways to exclude specific auto-configuration during testing:

  • exclude via properties in your application-test.properties
spring.autoconfigure.exclude=org.springframework.cloud.aws.messaging.config.annotation.SqsConfiguration
  • exclude via @TestPropertySource:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(classes = SQLTestConfig.class)
@TestPropertySource(properties ="spring.autoconfigure.exclude=org.springframework.cloud.aws.messaging.config.annotation.SqsConfiguration")

  • exclude via @EnableAutoConfiguration, e.g.:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(classes = SQLTestConfig.class)
@EnableAutoConfiguration(exclude=SqsConfiguration.class)

Choose one that suites you better ;)

Upvotes: 0

Related Questions