Recent Tutorials and Articles
    Overriding Active Profiles in Spring Boot Integration Tests
    Published on: 2018-09-17 04:09:30
    Posted By: Amit Kumar

    This tutorial demonstrates how to override the active profile from command line arguments in Spring Boot Integration Tests

    Abstract


    Spring Boot makes it easy for developers to write integration tests using SpringRunner class, @SpringBootTest and @ActiveProfiles. Here is a very simple integration test case -

    package com.example.demo;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
    @ActiveProfiles("dev")
    public class TestProfileOverridingDemoTests {
    
    	@Autowired
    	private TestRestTemplate testRestTemplate;
    	
    	@Test
    	public void testDemoContract() {
    		final ResponseEntity<String> responseEntity = testRestTemplate.getForEntity("/demo/123", String.class);
    		assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
    	}
    
    }

     

    In this IT, we have configured dev profile for our integration test. However, we will normally want to override this to run these cases in various environments such as CI (Jenkins) or performance.

     

    Overriding Profiles in Spring Boot Integration Tests


    We will now see how to override configured profile with the one passed through command line arguments. In order to do so, we will utilize resolver concept of @ActiveProfiles annotation.

    Here is a very basic profile resolver to override profile if passed as system property -

    package com.example.demo;
    
    import org.springframework.test.context.ActiveProfilesResolver;
    import org.springframework.test.context.support.DefaultActiveProfilesResolver;
    
    public class SystemPropertyActiveProfileResolver implements ActiveProfilesResolver {
        private final DefaultActiveProfilesResolver defaultActiveProfilesResolver = new DefaultActiveProfilesResolver();
    
        @Override
        public String[] resolve(Class<?> testClass) {
            final String springProfileKey = "spring.profiles.active";
    
            return System.getProperties().containsKey(springProfileKey)
                    ? System.getProperty(springProfileKey).split("\\s*,\\s*")
                    : defaultActiveProfilesResolver.resolve(testClass);
        }
    }

    Now let's see configure this resolver using resolver attribute of ActiveProfiles annotation.

    package com.example.demo;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
    @ActiveProfiles(value="dev", resolver=SystemPropertyActiveProfileResolver.class)
    public class TestProfileOverridingDemoTests {
    
    	@Autowired
    	private TestRestTemplate testRestTemplate;
    	
    	@Test
    	public void testDemoContract() {
    		final ResponseEntity<String> responseEntity = testRestTemplate.getForEntity("/demo/123", String.class);
    		assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
    	}
    
    }

    Now you can pass a system property from Maven or any of your build tool in order to override profile for integration tests.

    For Maven, you could pass following command to execute your integration tests with profile test -

    mvn clean test -Dspring.profiles.active=test

    You can verify activation of profile by looking at log statement similar to below -

    c.e.demo.TestProfileOverridingDemoTests  : The following profiles are active: test

     

    Thank you for reading through the tutorial. In case of any feedback/questions/concerns, you can communicate same to us through your comments and we shall get back to you as soon as possible.

    Posted By: Amit Kumar
    Published on: 2018-09-17 04:09:30

    Comment Form is loading comments...