Test JUnit5

Since Camel 3.0

The camel-test-junit5 module is used for unit testing Camel.

The class org.apache.camel.test.junit5.CamelTestSupport provides a base JUnit class which you would extend and implement your Camel unit test.

Simple unit test example

As shown below is a basic junit test which uses camel-test-junit5. The createRouteBuilder method is used for build the routes to be tested. Then the methods with @Test annotations are JUnit test methods which will be executed. The base class CamelTestSupport has a number of helper methods to configure testing, see more at the Javadoc of this class.

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;

public class SimpleMockTest extends CamelTestSupport {

    @Test
    public void testMock() throws Exception {
        getMockEndpoint("mock:result").expectedBodiesReceived("Hello World");

        template.sendBody("direct:start", "Hello World");

        MockEndpoint.assertIsSatisfied(context);
    }

    @Override
    protected RoutesBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() {
                from("direct:start").to("mock:result");
            }
        };
    }

}

Migrating Camel Tests from JUnit 4 to JUnit 5

Find below some hints to help in migrating camel tests from JUnit 4 to JUnit 5.

Projects using camel-test would need to use camel-test-junit5. For instance, maven users would update their pom.xml file as below:

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-test-junit5</artifactId>
  <scope>test</scope>
</dependency>
It’s possible to run JUnit4 & JUnit5 based Camel tests side by side including the following dependencies camel-test, camel-test-junit5 and junit-vintage-engine. This configuration allows migrating Camel tests one by one.

Migration Steps

  • Imports of org.apache.camel.test.junit4.* should be replaced with org.apache.camel.test.junit5.*

  • TestSupport static methods should be imported where needed, for instance import static org.apache.camel.test.junit5.TestSupport.assertIsInstanceOf

  • Usage of the field CamelTestSupport.log should be replaced by another logger, for instance org.slf4j.LoggerFactory.getLogger(MyCamelTest.class);

  • Usage of the method CamelTestSupport.createRegistry should be replaced by CamelTestSupport.createCamelRegistry()

  • Overrides of isCreateCamelContextPerClass() returning false should be removed

  • Overrides of isCreateCamelContextPerClass() returning true should be replaced by @TestInstance(Lifecycle.PER_CLASS)

  • Usage of the method CamelTestSupport.assertMockEndpointsSatisfied should be replaced by MockEndpoint.assertIsSatisfied(context)

Once Camel related steps have been performed, there are still typical JUnit 5 migration steps to remember:

  • New JUnit 5 assertions should be imported where needed, for instance import static org.junit.jupiter.api.Assertions.assertEquals

  • Assertion messages should be moved to the last parameter where needed, for instance assertEquals("message", 2, 1) becomes assertEquals(2, 1, "message")

  • org.junit.Test should be changed in favor of org.junit.jupiter.api.Test

  • org.junit.Ignore should be changed in favor of org.junit.jupiter.api.Disabled

  • org.junit.Before should be changed in favor of org.junit.jupiter.api.BeforeEach

  • org.junit.After should be changed in favor of org.junit.jupiter.api.AfterEach

  • org.junit.BeforeClass should be changed in favor of import org.junit.jupiter.api.BeforeAll

  • org.junit.AfterClass should be changed in favor of import org.junit.jupiter.api.AfterAll

  • Built-in assertThat from third-party assertion libraries should be used. For instance, use org.hamcrest.MatcherAssert.assertThat from java-hamcrest

Please check the JUnit 5 User Guide for additional insights about writing tests using JUnit 5.

Migration From Deprecated Configuration Methods

Camel 4.9 introduced two new interfaces to CamelTestSupport that will help users adjust their code and will help us with future maintenance of the test support code. These interfaces provide a stable APIs for code needing to configure the test behavior and the context configuration. The new interfaces are:

  • ConfigurableTest: that indicates that the test is configurable. This interface defines the methods configureTest and testConfiguration.

  • ConfigurableContext: that indicates that the context used in the test is configurable. This interface defines the methods configureContext and camelContextConfiguration.

During test setup, our code calls these methods at the most appropriate time. As such, user code doesn’t necessarily need to worry about when to call them.

Users willing to future-proof their code can leverage the two configuration methods provided by each of these interfaces and adjust their code so that the configuration is done inside them.

Consider, for instance, a test enabling JMX. Previously, that test would be written like this:

public class MyTestClass extends CamelTestSupport {
    // Other code here ...

    @Override
    protected boolean useJmx() {
        return false;
    }

    // More code here ...
}

This test can be migrated to the new API like this:

public class MyTestClass extends CamelTestSupport {
    // Other code here ...

    @Override
    public void configureTest(TestExecutionConfiguration testExecutionConfiguration) {
        testExecutionConfiguration.withEnableJMX();
    }

    // More code here ...
}

The same approach can be used for test code that configures the CamelContext. However, in this case, the configureContext method, which receives an instance of CamelContextConfiguration, can be used.