apache-camel Exemple de classe de test d'intégration Camel


Exemple

N'oubliez pas d'ajouter le support de test de chameau et le support de test de camel de printemps aux dépendances de votre projet. Voir les informations suivantes pour les utilisateurs de maven:

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-test</artifactId>
  <version>${camel.version}</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-spring</artifactId>
    <version>${camel.version}</version>
     <scope>test</scope>
</dependency>

Cette classe va déclencher et exécuter des tests sur l'exemple de route. Ces tests utilisent également DBUnit pour simuler une base de données, mais vous pouvez configurer votre contexte pour utiliser une base de données réelle ou autre.

Tout d'abord, nous utilisons une classe abstraite afin de partager des annotations communes entre chaque classe de test d'intégration Camel que nous utiliserons plus tard:

@RunWith(CamelSpringRunner.class)
@BootstrapWith(CamelTestContextBootstrapper.class)
@ContextConfiguration(locations = { "classpath:/test-beans.xml" })
@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
        DbUnitTestExecutionListener.class })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class AbstractCamelTI {

}

Attention à ne pas oublier les annotations ou vos DAO ne seront pas injectés correctement. Cela dit, vous pouvez supprimer en toute sécurité les annotations DBUnit si vous ne souhaitez pas utiliser la base de données décrite dans votre configuration de contexte.

IMPORTANT : J'ai ajouté le @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) récemment. De cette façon, le contexte camel est rechargé pour chaque test. Vous pouvez vraiment tester chaque partie de votre itinéraire individuellement. Cependant, si vous le voulez vraiment, vous devez utiliser remove () sur les parties de l'itinéraire choisi que vous ne souhaitez pas parcourir. Certains diront que ce n’est pas un véritable test d’intégration et qu’ils auront raison. Mais si, comme moi, vous avez besoin de gros processeurs, vous devez commencer par là.

Le code ci-dessous décrit le début de la classe de test (voir ci-dessous pour les tests réels):

@DatabaseSetup(value = { "/db_data/dao/common.xml", "/db_data/dao/importDocumentDAOCommonTest.xml" })
public class TestExampleProcessorTest extends AbstractCamelTI {

    @Autowired
    protected CamelContext camelContext;

    @EndpointInject(uri = "mock:catchTestEndpoint")
    protected MockEndpoint mockEndpoint;

    @Produce(uri = TestExampleRoute.ENDPOINT_EXAMPLE)
    protected ProducerTemplate template;

    @Autowired
    ImportDocumentTraitementDAO importDocumentTraitementDAO;

    // -- Variables for tests
    ImportDocumentProcess importDocumentProcess;

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();

        importDocumentProcess = new ImportDocumentProcess();
        //specific implementation of your choice
    }
}

Le test suivant est supposé déclencher la première partie de la route et l'amener à un mockEndpoint afin que nous puissions tester si ImportDocumentProcess a été correctement sélectionné et placé dans les en-têtes:

@Test
public void processCorrectlyObtained_getImportDocumentProcess() throws Exception {
    camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() {

        @Override
        public void configure() throws Exception {
            weaveById("getImportDocumentProcess").after().to(mockEndpoint);
        }
    });

    // -- Launching the route
    camelContext.start();
    template.sendBodyAndHeader(null, "entreprise", company);

    mockEndpoint.expectedMessageCount(1);
    mockEndpoint.expectedHeaderReceived(TestExampleProcessor.HEADER_UTILISATEUR, null);
    mockEndpoint.expectedHeaderReceived(TestExampleProcessor.HEADER_IMPORTDOCPROCESS, importDocumentProcess);
    mockEndpoint.assertIsSatisfied();

    camelContext.stop();
}

Le dernier test déclenche l'intégralité de l'itinéraire:

@Test
public void traitementCorrectlyCreated_createImportDocumentTraitement() throws Exception {
    camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() {

        @Override
        public void configure() throws Exception {
            weaveById("createImportDocumentTraitement").after().to(mockEndpoint);
        }
    });

    // -- Launching the route
    camelContext.start();

    Exchange exchange = new DefaultExchange(camelContext);
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_ENTREPRISE, company);
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_UTILISATEUR, null); // No user in this case
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_IMPORTDOCPROCESS, importDocumentProcess);

    long numberOfTraitementBefore = this.importDocumentTraitementDAO.countNumberOfImportDocumentTraitement();

    template.send(exchange);

    mockEndpoint.expectedMessageCount(1);
    mockEndpoint.assertIsSatisfied();

    camelContext.stop();

    long numberOfTraitementAfter = this.importDocumentTraitementDAO.countNumberOfImportDocumentTraitement();
    assertEquals(numberOfTraitementBefore + 1L, numberOfTraitementAfter);
}

Il est également possible de rediriger l'itinéraire actuel vers un autre processus. Mais je préfère rediriger vers un mockEndpoint . C'est un peu plus intéressant car vous pouvez vraiment faire des tests intermédiaires sur votre corps d'échange et vos en-têtes.


REMARQUE IMPORTANTE : Dans cet exemple, j'utilise le code suivant pour obtenir mes itinéraires et utiliser le adviceWith :

camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() { [...] });

Cependant, il est possible d’obtenir la route par un identifiant précédemment défini comme une chaîne, comme ceci:

 camelContext.getRouteDefinition("routeId").adviceWith(camelContext, new AdviceWithRouteBuilder() {  [...]  });

Je recommande fortement cette méthode, cela peut économiser beaucoup de temps à comprendre pourquoi vos tests échouent