Search code examples
javaspringspring-bootspring-ldap

Spring Boot Test: @TestPropertySource not overriding @EnableAutoConfiguration


I am using Spring Data LDAP to get user data from an LDAP server.

My file structure looks like this:

main
  java
    com.test.ldap
      Application.java
      Person.java
      PersonRepository.java
  resources
    application.yml
    schema.ldif

test
  java
    Tests.java
  resources
    test.yml
    test_schema.ldif

And here is my test class:

import com.test.ldap.Person;
import com.test.ldap.PersonRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {PersonRepository.class})
@TestPropertySource(locations = "classpath:test.yml")
@EnableAutoConfiguration
public class Tests {

    @Autowired
    private PersonRepository personRepository;

    @Test
    public void testGetPersonByLastName() {
        List<Person> names = personRepository.getPersonNamesByLastName("Bachman");
        assert(names.size() > 0);
    }

}

The problem is, Spring Boot is loading the application.yml and schema.ldif files instead of my test YAML and LDIF files, despite the fact that my @TestPropertySource annotation is explicitly listing test.yml. This seems to be due to the auto configuration, which I would prefer to use for convenience.

I would expect @TestPropertySource to take higher precedence than the auto configuration, but that does not seem to be the case. Is this a bug in Spring, or am I misunderstanding something?

For the record, here is my test.yml file (it does specify test_schema.ldif):

spring:
  ldap:
    # Embedded Spring LDAP
    embedded:
      base-dn: dc=test,dc=com
      credential:
        username: uid=admin
        password: secret
      ldif: classpath:test_schema.ldif
      port: 12345
      validation:
        enabled: false

Solution

  • So I was able to work around this by manually specifying the properties needed to make use of the LDIF file. This is because, according to the @TestPropertySource documentation, inlined properties have higher preferences than property files.

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {PersonRepository.class})
    @TestPropertySource(properties = 
    {"spring.ldap.embedded.ldif=test_schema.ldif", "spring.ldap.embedded.base-dn=dc=test,dc=com"})
    @EnableAutoConfiguration
    public class Tests {
        //...
    }
    

    This is not the best workaround, however: what if I had more than just two properties I needed to define? It would be impractical to list them all there.

    Edit:

    Renaming my test.yml file to application.yml so it overrides the production file that way did the trick. As it turns out, the TestPropertySource annotation only works for .properties files.