Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until tomorrow:

>> GET ACCESS NOW

November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until tomorrow:

>> GET ACCESS NOW

1. Overview

In this quick tutorial, we'll discuss how to exclude auto-configuration classes from Spring Boot tests.

Spring Boot's auto-configuration feature is very handy, as it takes care of a lot of setup for us. However, this can also be an issue during testing if we don't want a certain auto-configuration to interfere with our tests of a module.

A common example of this is the security auto-configuration, which we'll also use for our examples.

2. Test Example

First, we'll take a look at our testing example.

We'll have a secured Spring Boot application with a simple home page.

When we try to access the home page without authentication, the response is “401 UNAUTHORIZED”.

Let's see this in a test that uses REST-assured to make the call:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class AutoConfigIntegrationTest {

    @Test
    public void givenNoAuthentication_whenAccessHome_thenUnauthorized() {
        int statusCode = RestAssured.get("http://localhost:8080/").statusCode();
        
        assertEquals(HttpStatus.UNAUTHORIZED.value(), statusCode);
    }
    
}

On the other hand, we can access the home page successfully with authentication:

@Test
public void givenAuthentication_whenAccessHome_thenOK() {
    int statusCode = RestAssured.given().auth().basic("john", "123")
      .get("http://localhost:8080/")
      .statusCode();
    
    assertEquals(HttpStatus.OK.value(), statusCode);
}

In the following sections, we'll try different ways to exclude the SecurityAutoConfiguration class from our tests' configuration.

3. Using @EnableAutoConfiguration

There are multiple ways to exclude a specific Auto-configuration class from tests' configuration.

First, let's see how we can use the @EnableAutoConfiguration(exclude={CLASS_NAME}) annotation:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@EnableAutoConfiguration(exclude=SecurityAutoConfiguration.class)
public class ExcludeAutoConfigIntegrationTest {

    @Test
    public void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
        int statusCode = RestAssured.get("http://localhost:8080/").statusCode();
        
        assertEquals(HttpStatus.OK.value(), statusCode);
    }
}

In this example, we excluded the SecurityAutoConfiguration class using the exclude attribute, but we can do the same with any of the auto-configuration classes.

Now we can run our test that accesses the home page without authentication and it will no longer fail.

4. Using @TestPropertySource

Next, we can use @TestPropertySource to inject the property “spring.autoconfigure.exclude:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = 
 "spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration")
public class ExcludeAutoConfigIntegrationTest {
    // ...
}

Note that we need to specify the full class name (package name+simple name) for the property.

5. Using Profiles

We can also set the property “spring.autoconfigure.exclude” for our tests using profiles:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@ActiveProfiles("test")
public class ExcludeAutoConfigIntegrationTest {
    // ...
}

And include all “test” profile specific properties in application-test.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

6. Using a Custom Test Configuration

Finally, we can use a separate configuration application for our tests:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class ExcludeAutoConfigIntegrationTest {
    // ...
}

And exclude the auto-configuration class from @SpringBootApplication(exclude={CLASS_NAME}):

@SpringBootApplication(exclude=SecurityAutoConfiguration.class)
public class TestApplication {

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

7. Conclusion

In this article, we explored different ways to exclude auto-configuration classes from Spring Boot tests.

The full source code is available over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until tomorrow:

>> GET ACCESS NOW

Junit footer banner
Comments are closed on this article!