web-dev-qa-db-fra.com

Source de données Spring Boot dans les tests unitaires

J'ai une application Web Spring Boot simple, qui lit dans une base de données et renvoie une réponse JSON. J'ai la configuration de test suivante:

@RunWith(SpringRunner.class)
@SpringBootTest(classes=MyApplication.class, properties={"spring.config.name=myapp"})
@AutoConfigureMockMvc
public class ControllerTests {
    @Autowired
    private MockMvc mvc;
    @MockBean
    private ProductRepository productRepo;
    @MockBean
    private MonitorRepository monitorRepo;

    @Before
    public void setupMock() {
        Mockito.when(productRepo.findProducts(anyString(), anyString()))
        .thenReturn(Arrays.asList(dummyProduct()));     
    }

    @Test
    public void expectBadRequestWhenNoParamters() throws Exception {    
        mvc.perform(get("/products"))
                .andExpect(status().is(400))
                .andExpect(jsonPath("$.advice.status", is("ERROR")));
    }

    //other tests
}

J'ai un bean DataSource qui est configuré dans la configuration principale de l'application. Lorsque j'exécute les tests, Spring essaie de charger le contexte et échoue car la source de données provient de JNDI. En général, je veux éviter de créer une source de données pour ces tests, car les référentiels sont fictifs.

Est-il possible d'ignorer la création d'une source de données lors de l'exécution des tests unitaires?

En mémoire, la base de données à tester n'est pas une option car mon script de création de base de données a une structure spécifique et ne peut pas être exécuté facilement à partir de classpath: schema.sql

Edit La source de données est définie dans MyApplication.class

    @Bean
    DataSource dataSource(DatabaseProeprties databaseProps) throws NamingException {
       DataSource dataSource = null;
       JndiTemplate jndi = new JndiTemplate();
       setJndiEnvironment(databaseProps, jndi);
       try {
           dataSource = jndi.lookup(databaseProps.getName(), DataSource.class);
       } catch (NamingException e) {
           logger.error("Exception loading JNDI datasource", e);
           throw e;
       }
       return dataSource;
   }
4
Evgeni Dimitrov

Puisque vous chargez la classe de configuration MyApplication.class, un bean de source de données sera créé. Essayez de déplacer la source de données dans un autre bean non utilisé dans un test. Assurez-vous que toutes les classes chargées pour les tests ne dépendent pas de la source de données.
Ou 
Dans vos tests, créez une classe de configuration marquée avec @TestConfiguration et incluez-la dans la source de données moqueuse SpringBootTest(classes=TestConfig.class), comme ceci: 

@Bean
public DataSource dataSource() {
    return Mockito.mock(DataSource.class);
}

Mais cela peut échouer car l’appel de méthode à cette datasouce simulée pour connection renverra null. Dans ce cas, vous devrez créer une source de données en mémoire, puis simuler jdbcTemplate et le reste des dépendances.

6
Mayur

Essayez d’ajouter votre source de données en tant que @MockBean aussi:

@MockBean
private DataSource dataSource

De cette façon, Spring effectuera la logique de remplacement pour vous, avec l'avantage que la création de votre bean de code de production ne sera même pas exécutée (aucune recherche JNDI).

1
wjans