Close

Spring Testing - ProfileValueSource Example

[Updated: Jul 3, 2017, Created: Jul 2, 2017]

This example demonstrates how to use ProfileValueSource and @ProfileValueSourceConfiguration to specify a custom strategy for retrieving profile values for a given testing environment.

Rather than using the default SystemProfileValueSource (check out the last tutorial), a custom implementation of ProfileValueSource can be configured on a test class by using @ProfileValueSourceConfiguration. When @IfProfileValue is used in the same class, it's value is tested against the value returned from ProfileValueSource#get(String key) to enable or disable the corresponding test. Let's understand that with an example.

Example

Creating a Simple Spring application

@Service
public class ReportService {

  public String getReport() {
      return "some report";
  }
}
@Configuration
@ComponentScan
public class AppConfig {

}

Implementing ProfileValueSource

This implementation first attempts to retrieve the value for the provided 'key' from Properties loaded from a property file. If not present (if null) then tries the System properties for the same key.

public class MyProfileValueSource implements ProfileValueSource {
  private final Properties testProps;

  public MyProfileValueSource() {

      ClassPathResource resource = new ClassPathResource("test.properties");
      if (resource.exists()) {
          try {
              this.testProps = PropertiesLoaderUtils.loadProperties(resource);
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
      }else{
          testProps = new Properties();
      }
  }

  @Override
  public String get(String key) {
      return testProps.getProperty(key, System.getProperty(key));
  }
}

src/main/resources/test.properties

report.enabled=false

The JUnit test

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppConfig.class)
@ProfileValueSourceConfiguration(MyProfileValueSource.class)
public class ServiceTests {

  @Autowired
  private ReportService reportService;

  @Test
  @IfProfileValue(name = "report.enabled", value = "true")
  public void testReport() {
      String s = reportService.getReport();
      System.out.println(s);
      Assert.assertEquals("some report", s);
  }
}
mvn -q test -Dtest=ServiceTests -DfailIfNoTests=false

Output

D:\example-projects\spring-core-testing\profile-value-source-example>mvn -q test -Dtest=ServiceTests -DfailIfNoTests=false

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.logicbig.example.ServiceTests
Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.136 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 1

The test was skipped. We can enable the method by setting report.enabled=true in the property file without changing the code.

Example Project

Dependencies and Technologies Used:

  • spring-context 4.3.8.RELEASE: Spring Context.
  • spring-test 4.3.9.RELEASE: Spring TestContext Framework.
  • junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 1.8
  • Maven 3.3.9

Profile Value Source Select All Download
  • profile-value-source-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • resources
      • test
        • java
          • com
            • logicbig
              • example

See Also