web-dev-qa-db-fra.com

@DataJpaTest a besoin d'une classe en dehors du test

Dans une application SpringBoot, je voudrais faire un test sur la couche de référentiel.

@RunWith(SpringRunner.class)
@DataJpaTest
public class VisitRepositoryTest {

     @Autowired
     private TestEntityManager entityManager;

     @Autowired
     private VisitRepository visitRepository;

     ...
}

Lorsque j'essaie d'exécuter le test à partir de VisitRepositoryTest, j'obtiens une erreur concernant DefaultConfigService

Le champ defaultConfigService dans com.norc.Application a nécessité un bean de type 'com.norc.service.DefaultConfigService' introuvable.

Donc, cela doit exécuter le Application?

J'ai essayé de mettre un bean de DefaultConfigService dans VisitRepositoryTest, mais ce n'est pas autorisé.

Cette classe est utilisée dans mon application

@EntityScan(basePackageClasses = {Application.class, Jsr310JpaConverters.class})
@SpringBootApplication
@EnableScheduling
public class Application implements SchedulingConfigurer {

      @Autowired
      private DefaultConfigService defaultConfigService;
      ...
}

Comment gérer ça?


Éditer

Dans mon application, j'utilise cette classe dans un onglet cron:

@Service
public class DefaultConfigServiceImpl implements DefaultConfigService {

    private final DefaultConfigRepository defaultConfigRepository;

    @Autowired
    public DefaultConfigServiceImpl(final DefaultConfigRepository defaultConfigRepository) {
         this.defaultConfigRepository = defaultConfigRepository;
    }
}
17
robert trudel

Le problème est que votre @SpringBootApplication A une configuration supplémentaire concernant la planification et en ajoutant qu'il n'y a pas de @SpringBootConfiguration Personnalisé pour votre test, une telle exigence de planification devient obligatoire pour tout.

Prenons un peu de recul. Lorsque vous ajoutez @DataJpaTest, Spring Boot doit savoir comment bootstrap votre contexte d'application. Il doit trouver vos entités et vos référentiels. Les tests de tranche rechercheront récursivement un @SpringBootConfiguration: D'abord dans le package de votre test réel, puis le parent, puis le parent et s'il n'en trouve pas, il lèvera une exception.

@SpringBootApplication Est un @SpringBootConfiguration Donc si vous ne faites rien de spécial, les tests de tranche utiliseront votre application comme source de configuration (qui est IMO, une excellente valeur par défaut).

Les tests de tranche ne démarrent pas aveuglément votre application (sinon ce ne serait pas du découpage), donc ce que nous faisons est de désactiver la configuration automatique et de personnaliser l'analyse des composants pour la tâche à accomplir (uniquement en analysant les entités et les référentiels et en ignorant tout le reste lorsque vous utilisez @DataJpaTest). C'est un problème pour vous car la configuration de l'application est appliquée et les éléments de planification doivent être disponibles. Mais les beans dépendants ne sont pas analysés.

Dans votre cas, si vous souhaitez utiliser le découpage, la configuration de la planification doit passer à un SchedulingConfiguration ou quelque chose (elle ne sera pas analysée avec un découpage comme expliqué ci-dessus). Quoi qu'il en soit, je pense qu'il est plus propre de séparer une implémentation de SchedulingConfigurer de toute façon. Si vous faites cela, vous remarquerez que l'erreur disparaîtra.

Supposons maintenant que vous vouliez pour ce test particulier que FooService soit également disponible. Plutôt que d'activer l'analyse des composants comme le suggère Dimitrisli (c'est-à-dire désactiver essentiellement le découpage pour votre configuration), vous pouvez simplement importer la classe manquante

@RunWith(SpringRunner.class)
@DataJpaTest
@Import(FooService.class)
public class VisitRepositoryTest {
  ...
}
52
Stephane Nicoll