1.4. 测试 Camel Quarkus 扩展


测试提供了一种不错的方法,可以确保 Camel 路由随着时间的推移的行为。如果您还没有这么做,请阅读 Camel Quarkus 用户指南 First Steps 和 Quarkus 文档 link:Testing your application 部分。

在 Quarkus 中测试路由的最简单方法是编写本地集成测试。这具有涵盖 JVM 和原生模式的优点。

在 JVM 模式中,您可以使用测试的 CamelTestSupport 样式。

1.4.1. 在 JVM 模式下运行

在 JVM 模式中,使用 @QuarkusTest 注释到 bootstrap Quarkus 并启动 Camel 路由,然后再执行 @Test 逻辑。

例如:

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

@QuarkusTest
class MyTest {
    @Test
    public void test() {
        // Use any suitable code that sends test data to the route and then assert outcomes
        ...
    }
}
提示

您可以在 Camel Quarkus 源中找到示例实现:

1.4.2. 在原生模式下运行

注意

始终测试您的应用程序是否在所有支持的扩展中以原生模式工作。

您可以通过从相应的 JVM 模式类继承逻辑来重复利用为 JVM 模式定义的测试逻辑。

添加 @QuarkusIntegrationTest 注释,以指示 Quarkus JUnit 扩展将测试下的应用编译到原生镜像,并在运行测试前启动它。

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
class MyIT extends MyTest {
   ...
}
提示

您可以在 Camel Quarkus 源中找到示例实现:

原生可执行文件不需要 JVM 运行,且无法在 JVM 中运行,因为它是原生代码,而不是字节码。

对原生代码进行编译测试没有点,因此它们使用传统的 JVM 运行。

这意味着,测试和应用之间的通信必须经过网络(HTTP/REST),或者您的应用通过监视文件系统(例如日志文件)或其他进程间通信的其他协议。

1.4.3.1. JVM 模式中的 @QuarkusTest

在 JVM 模式中,使用 @QuarkusTest 注释的测试在与 test 下的应用相同的 JVM 中执行。

这意味着您可以使用 @Inject 将应用中的 Bean 添加到测试代码中。

您还可以使用 @javax.enterprise.inject.Alternative 和 @javax.annotation.Priority 定义新的 Bean,甚至覆盖应用中的 Bean。

1.4.3.2. @QuarkusIntegrationTest in native mode

在原生模式中,以 @QuarkusIntegrationTest 执行注释为 @QuarkusIntegrationTest 执行,其在与正在运行的原生应用分开的 JVM 中执行。

QuarkusIntegrationTest 提供了通过 @QuarkusTest 不提供的其他功能:

  • 在 JVM 模式中,您可以启动并测试 Quarkus 构建生成的可运行的应用 JAR。
  • 在原生模式中,您可以启动并测试 Quarkus 构建生成的原生应用程序。
  • 如果您在构建中添加容器镜像,则启动容器并针对它执行测试。

有关 QuarkusIntegrationTest 的更多信息,请参阅 Quarkus 测试指南。

1.4.4. 使用外部服务测试

1.4.4.1. Testcontainers

有时您的应用程序需要访问一些外部资源,如消息传递代理、数据库或其他服务。

如果容器镜像可用于感兴趣的服务,您可以在测试过程中使用 Testcontainers 启动并启用服务。

要使应用正常工作,在启动前,将连接配置数据(主机、端口、用户、远程服务的密码)传递给应用程序。

在 Quarkus 生态系统中,QuarkusTestResourceLifecycleManager 为这个目的。

您可以使用 start () 方法启动一个或多个 Testcontainers,并以 Map 的形式从方法返回连接配置。

然后,此映射的条目会根据模式以不同的方式传递给应用程序:

  • 原生模式:命令行(-Dkey=value)
  • JVM 模式:特殊的 MicroProfile 配置提供程序
注意

这些设置的优先级高于 application.properties 文件中的设置。

import java.util.Map;
import java.util.HashMap;

import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;

public class MyTestResource implements QuarkusTestResourceLifecycleManager {

    private GenericContainer myContainer;

    @Override
    public Map<String, String> start() {
        // Start the needed container(s)
        myContainer = new GenericContainer(...)
                .withExposedPorts(1234)
                .waitingFor(Wait.forListeningPort());

        myContainer.start();

        // Pass the configuration to the application under test
        return new HashMap<>() {{
                put("my-container.host", container.getContainerIpAddress());
                put("my-container.port", "" + container.getMappedPort(1234));
        }};
    }

    @Override
    public void stop() {
        // Stop the needed container(s)
        myContainer.stop();
        ...
    }

使用 @QuarkusTestResource 从测试类引用定义的测试资源:

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
@QuarkusTestResource(MyTestResource.class)
class MyTest {
   ...
}
提示

您可以在 Camel Quarkus 源中找到示例实现:

1.4.4.2. WireMock

您可以不将测试连接到实时端点,例如,如果它们不可用、不可靠或昂贵,您可以与第三方服务和 API 进行 stub HTTP 交互。

您可以使用 WireMock 模拟和记录 HTTP 交互。它在整个 Camel Quarkus 测试套件中广泛用于各种组件扩展。

1.4.4.2.1. 设置 WireMock

流程

  1. 设置 WireMock 服务器。

    注意

    在测试下配置 Camel 组件非常重要,以通过 WireMock 代理传递任何 HTTP 交互。您可以通过配置决定 API 端点 URL 的组件属性来实现此目的。

    import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
    import static com.github.tomakehurst.wiremock.client.WireMock.get;
    import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
    import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import com.github.tomakehurst.wiremock.WireMockServer;
    
    import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
    
    public class WireMockTestResource implements QuarkusTestResourceLifecycleManager {
    
        private WireMockServer server;
    
        @Override
        public Map<String, String> start() {
            // Setup & start the server
            server = new WireMockServer(
                wireMockConfig().dynamicPort()
            );
            server.start();
    
            // Stub a HTTP endpoint. Note that WireMock also supports a record and playback mode
            // http://wiremock.org/docs/record-playback/
            server.stubFor(
                get(urlEqualTo("/api/greeting"))
                    .willReturn(aResponse()
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"message\": \"Hello World\"}")));
    
            // Ensure the camel component API client passes requests through the WireMock proxy
            Map<String, String> conf = new HashMap<>();
            conf.put("camel.component.foo.server-url", server.baseUrl());
            return conf;
        }
    
        @Override
        public void stop() {
            if (server != null) {
                server.stop();
            }
        }
    }
    注意

    有时并不简单,需要一些额外的工作来配置 API 客户端库。例如,对于 Twilio。

  2. 确保您的测试类具有 @QuarkusTestResource 注释,并将适当的 test 资源类指定为值。
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
@QuarkusTestResource(WireMockTestResource.class)
class MyTest {
   ...
}

WireMock 服务器在所有测试都执行和关闭之前启动,并在所有测试完成后关闭。

提示

您可以在 Camel Quarkus 集成测试源树中找到示例实现:

1.4.5. 使用 CamelQuarkusTestSupport

由于 Camel Quarkus 2.13.0,您可以使用 CamelQuarkusTestSupport 进行测试。它是 CamelTestSupport 的替代。

注意

这将仅在 JVM 模式下工作。

将以下依赖项添加到您的模块中(最好在 测试 范围内):

<dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-junit5</artifactId>
    <scope>test</scope>
</dependency>

您可以在测试中使用 CamelQuarkusTestSupport,如下所示:

@QuarkusTest
@TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance)
public class SimpleTest extends CamelQuarkusTestSupport {
    ...
}

1.4.5.2. 使用 CamelQuarkusTestSupport时的限制

使用 'CamelQuarkusTestSupport 时,有几个限制:

1.4.5.2.1. Methods

有些方法并不执行。使用以 do 开头的新方法:

未执行使用 替代

afterAll

doAfterAll

afterEach

doAfterEach

afterTestExecution

doAfterTestExecution

beforeAll

doBeforeAll

beforeEach

doBeforeEach

注意

如果您使用 @TestInstance (TestInstance.Lifecycle.PER_METHOD),则 doAfterConstruct 意味着在每次测试前的回调。这与 beforeAll 有所不同。

1.4.5.2.2. 注解

您必须使用 @io.quarkus.test.junit.QuarkusTest 来注解测试类,并扩展 org.apache.camel.quarkus.test.CamelQuarkusTestSupport。

1.4.5.2.3. 启动和停止
  • 您不能在单个应用程序的生命周期中停止并重启相同的 CamelContext 实例。您可以调用 CamelContext.stop (),但 CamelContext.start () 将无法工作。
  • CamelContext 通常绑定到启动和停止应用程序,在测试时也相关。
  • 测试下的应用针对给定的 Maven/Gradle 模块的所有测试类都启动一次。Quarkus JUnit Extension 控制应用的启动和停止。您必须明确告知应用程序需要停止。
1.4.5.2.4. 重启应用程序

要强制 Quarkus JUnit 扩展为给定的测试类重新启动应用和 CamelContext,您需要将唯一的 @io.quarkus.test.junit.TestProfile 分配给该类。

具体步骤请参阅 Quarkus 文档中的 测试不同配置集。

对于类似效果,您也可以使用 @io.quarkus.test.common.QuarkusTestResource。

1.4.5.2.5. Bean production

Camel Quarkus 在构建阶段执行 Bean 的生产。由于测试是一起构建的,因此排除行为在 CamelQuarkusTestSupport 中实现。如果一个测试中使用了特定类型的和名称的制作者,则实例将会与其余测试相同。

1.4.5.2.6. JUnit Jupiter 回调可能无法工作

这些 JUnit Jupiter 回调和注解可能无法正常工作:

回调注解

BeforeEachCallback

@BeforeEach

AfterEachCallback

@AfterEach

AfterAllCallback

@AfterAll

BeforeAllCallback

@BeforeAll

BeforeTestExecutionCallback

 

AfterTestExecutionCallback

 

如需更多信息,请参阅通过 QuarkusTest* 回调文档 增强。

1.4.5.2.7. 使用建议With

当 recommendations With 设为 true 时,所有未推荐的路由都不会启动。您必须执行 CamelQuarkusTestSupport.startRouteDefinitions () 方法,以便这些路由启动它们。

1.4.5.2.8. 使用 @Produces

将 @Produces 与覆盖的方法 createRouteBuilder () 一起使用。@Produces 和 RouteBuilder () 的组合可能无法正常工作。

1.4.5.2.9. 配置路由

要将应用程序中的路由(src/main/java)配置为包含或排除,您可以使用:

  • quarkus.camel.routes-discovery.exclude-patterns
  • quarkus.camel.routes-discovery.include-patterns

如需了解更多详细信息,请参阅 Core 文档。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

关于红帽文档

Legal Notice

Theme

© 2026 Red Hat
返回顶部