Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude Spring Cloud Config Server from Spring boot unit test

Given I have the following 3 Beans:

@Component
public class ServiceConfig {
    // This value is only available from the Spring Cloud Config Server
    @Value("${example.property}")
    private String exampleProperty;

    public String getExampleProperty() {
        return exampleProperty;
    }
}

@Component
public class S1 {
    int i = 1;
}

@Component
public class S2 {

    @Autowired
    S1 s1;

}

I want to be able to run the following test:

@RunWith(SpringRunner.class)
@SpringBootTest
public class S2Test {

    @Autowired
    S2 s;

    @Test
    public void t2() {
        System.out.println(s.s1.i);
    }

}

The issue I have is that since I want to test the S2 class in isolation and since it uses @Autowired I must have a Spring context in my test, however when the Spring context is started it tries to create all 3 beans which includes the bean with @Value. Since this value is only available from Spring Cloud Config Server the context will fail to be created giving the error: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'example.property' in string value "${example.property}".

My Question is: How are properties read from Spring Cloud Config Server handled in the application when unit tests are run, observe in my test i dont even care about the config so I dont want to explicitly have to set a value in my test just for the context to be started?

like image 956
user3139545 Avatar asked Sep 11 '17 17:09

user3139545


2 Answers

I would suggest simply adding "spring.cloud.config.enabled" to false in "src/test/resources/application.properties" and adding a test value for "example.property"..

spring.cloud.config.enabled=false
example.property=testvalue

This is simple and does not impact your code base. IF needed, you could also us a MOCK web environment, and a custom test application configuration that does not include those beans.

@SpringBootTest(classes = TestOnlyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
like image 137
Pytry Avatar answered Oct 03 '22 19:10

Pytry


There is some options.

  1. You can create test profile. Then, you will need to create application-test.yml or application-test.properties file. There, you can set the same value for example.property. There, if you want to start some tests with test profile, you can add to your test class @ActiveProfiles("test") annotation. For these tests, test would be started.

  2. You can set default value for example.property by typing @Value("${example.property:SomeDefaultValue}"). SomeDefaultValue will be inserted if property not found.

I'd suggest first approach. You can set proper profile with annotation and there you will make sure which profile config server will send to you.

like image 37
Artur Czopek Avatar answered Oct 03 '22 19:10

Artur Czopek