web-dev-qa-db-fra.com

@TestPropertySource ne fonctionne pas pour le test JUnit avec AnnotationConfigContextLoader au printemps 1.2.6

Il ne semble pas que ce que je fais dans Spring 4.1.17 avec Spring Boot 1.2.6.RELEASE fonctionne du tout. Je veux juste accéder aux propriétés de l'application et les remplacer par test si nécessaire (sans utiliser le hack pour injecter une PropertySource manuellement)

ça ne marche pas ..

@TestPropertySource(properties = {"elastic.index=test_index"})

ni cela ..

@TestPropertySource(locations = "/classpath:document.properties")

ni cela ..

@PropertySource("classpath:/document.properties")

cas de test complet ..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@TestPropertySource(properties = {"elastic.index=test_index"})
public class PropertyTests {
    @Value("${elastic.index}")
    String index;

    @Configuration
    @TestPropertySource(properties = {"elastic.index=test_index"})
    static class ContextConfiguration {
    }

    @Test
    public void wtf() {
        assertEquals("test_index", index);
    }
}

résultant en

org.junit.ComparisonFailure: 
Expected :test_index
Actual   :${elastic.index}

Il semble qu'il y ait beaucoup d'informations contradictoires entre 3.x et 4.x et je ne trouve rien qui puisse fonctionner à coup sûr.

Toute idée serait grandement appréciée. À votre santé!

25
Thomas Beauvais

Il semble que le meilleur moyen (jusqu'à ce que Spring corrige cet oubli) consiste à utiliser un PropertySourcesPlaceholderConfigurer qui apportera test.properties (ou ce que vous voudrez) et @Import ou étendre cela @Configuration.

import org.Apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import Java.io.IOException;

@Configuration
public class PropertyTestConfiguration {
    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws IOException {
        final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocations(ArrayUtils.addAll(
                        new PathMatchingResourcePatternResolver().getResources("classpath*:application.properties"),
                        new PathMatchingResourcePatternResolver().getResources("classpath*:test.properties")
                )
        );

        return ppc;
    }

}

Cela vous permet de définir des valeurs par défaut dans application.properties et de les remplacer dans test.properties. Bien entendu, si vous avez plusieurs schémas, vous pouvez configurer la classe PropertyTestConfiguration si nécessaire.

Et utilisez ceci dans un test unitaire.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PropertyTests {
    @Value("${elastic.index}")
    String index;

    @Configuration
    @Import({PropertyTestConfiguration.class})
    static class ContextConfiguration {
    }
}
14
Thomas Beauvais

J'ai utilisé la propriété locations de @TestPropertySource pour remplacer (ou ajouter) des propriétés.

Cela a fonctionné pour moi (printemps 4.2.4):

@TestPropertySource(locations = {
   "classpath:test.properties",
   "classpath:test-override.properties" })

Mais les propriétés primordiales comme ci-dessous ne l'ont pas fait:

@TestPropertySource(
  locations = {"classpath:test.properties"},
  properties = { "key=value" })

Même si le javadoc indique que ces propriétés ont la priorité la plus élevée. Un bug peut-être?

Mettre à jour

Le bogue devrait être corrigé dans Spring Boot version 1.4.0 et ultérieure. Voir le commit qui ferme le problème . A présent, les propriétés déclarées de la manière présentée devraient avoir la priorité.

14
sorrymissjackson

Votre utilisation de @Value nécessite un bean PropertySourcesPlaceholderConfigurer pour résoudre ${...} espaces réservés. Voir la réponse acceptée ici: @ Valeur non définie via le contexte de test configuré par Java

6
Don Bottstein

Pour moi, @TestPropertySource ("classpath: xxxxxxxx.properties") a fonctionné

4
Swarit Agarwal

Avez-vous essayé d'utiliser @PropertySource("classpath:document.properties") ou @PropertySource("classpath*:document.properties")?

3
user2004685

J'ai eu un problème avec @TestPropertySource. test.properties non trouvé

ci-dessous est celui avant fixé

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ExtContext.class)
@TestPropertySource(locations = "classpath: test.properties")

j'ai supprimé l'espace entre classpath: et test.properties comme ci-dessous

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ExtContext.class)
@TestPropertySource(locations = "classpath:test.properties")

Cela a fonctionné pour moi, lorsque test.properties n'est pas trouvé dans classpth. Misht travaille pour vous aussi

1
S.Sriniavasulu