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;
}
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.
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).