1.4. 测试 Camel Quarkus 扩展


测试提供了一种确保 Camel 路由与预期随着时间的推移的好方法。如果您还没有这样做,请阅读 Camel Quarkus 用户指南第一步和 Quarkus 文档 测试应用程序 部分。https://camel.apache.org/camel-quarkus/3.8.x/user-guide/first-steps.html

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

在 JVM 模式中,您可以使用 CamelTestSupport 风格测试

1.4.1. 在 JVM 模式下运行

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

例如:

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
        ...
    }
}
Copy to Clipboard Toggle word wrap
提示

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

1.4.2. 在原生模式下运行

注意

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

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

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

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
class MyIT extends MyTest {
   ...
}
Copy to Clipboard Toggle word wrap
提示

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

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

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

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

1.4.3.1. JVM 模式中的 @QuarkusTest

在 JVM 模式中,带有 @QuarkusTest 标注的测试在与测试下的应用相同的 JVM 中执行。

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

您还可以使用 @jakarta. enterprise.inject.Alternative 和 @jakarta.annotation.Priority 来定义新的 Bean,甚至覆盖来自应用程序的 Bean。

1.4.3.2. 原生模式的 @QuarkusIntegrationTest

在原生模式中,在独立于正在运行的原生应用的进程中托管的 JVM 中带有 @QuarkusIntegrationTest 执行的测试。

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();
        ...
    }
Copy to Clipboard Toggle word wrap

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

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

@QuarkusTest
@QuarkusTestResource(MyTestResource.class)
class MyTest {
   ...
}
Copy to Clipboard Toggle word wrap
提示

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

1.4.4.2. WireMock

例如,如果测试不可用、不可靠或昂贵,您可以与第三方服务和 API 存根 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();
            }
        }
    }
    Copy to Clipboard Toggle word wrap
    注意

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

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

@QuarkusTest
@QuarkusTestResource(WireMockTestResource.class)
class MyTest {
   ...
}
Copy to Clipboard Toggle word wrap

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>
Copy to Clipboard Toggle word wrap

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

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

1.4.5.2. 使用 CamelQuarkusTestSupport时的限制

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

1.4.5.2.1. Methods

有些方法没有执行。使用以 开头 的新方法

Expand
未执行改为使用

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 通常绑定到启动和停止应用程序(在测试时)。
  • test 下的应用程序会针对给定 Maven/Gradle 模块的所有测试类启动一次。Quarkus JUnit Extension 控制应用程序的启动和停止。您必须明确告知应用程序停止。
1.4.5.2.4. 重启应用程序

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

具体步骤请查看 Quarkus 文档中的 测试不同配置集

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

1.4.5.2.5. Bean 生产

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

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

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

Expand
回调注解

BeforeEachCallback

@BeforeEach

AfterEachCallback

@AfterEach

AfterAllCallback

@AfterAll

BeforeAllCallback

@BeforeAll

BeforeTestExecutionCallback

 

AfterTestExecutionCallback

 

如需更多信息,请参阅通过 QuarkusTest*Callback 文档 Enrichment

1.4.5.2.7. 使用 recommendationsWith

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

1.4.5.2.8. 使用 @Produces

使用带有覆盖方法 createRouteBuilder ()@Produces@ProducesRouteBuilder () 的组合可能无法正常工作。

1.4.5.2.9. 配置路由

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

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

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

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

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

關於紅帽

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

Theme

© 2026 Red Hat
返回顶部