1.4. 测试 Camel Quarkus 扩展


测试提供了一种好的方法来确保 Camel 路由在一段时间内的行为正常。如果您还没有,请阅读 Camel Quarkus 用户指南,首先步骤和 Quarkus 文档链接:测试应用程序 部分。

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

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

1.4.1. 在 JVM 模式下运行

在 JVM 模式中,使用 @QuarkusTest 注释引导 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 添加到测试代码中。

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

1.4.3.2. @QuarkusIntegrationTest in native mode

在原生模式中,使用 @QuarkusIntegrationTest 注解的测试在独立于正在运行的原生应用程序的 JVM 中执行。

QuarkusIntegrationTest 提供了通过 @QuarkusTest 不提供的额外功能:

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

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

1.4.4. 使用外部服务测试

1.4.4.1. testcontainers

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

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

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

在 Quarkus 生态系统中,QuarkusTestResourceLifecycleManager 提供了这一目的。

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

然后,此映射的条目以不同的方式传递给应用程序,具体取决于模式:

  • 原生模式:命令行(-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 引用测试类中定义的 test 资源:

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 服务器。

    注意

    在 test 下配置 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. 确保您的测试类具有 @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

某些方法无法执行。使用以 do 开头的新方法:

Expand
未执行改为使用

afterAll

doAfterAll

afterEach

doAfterEach

afterTestExecution

doAfterTestExecution

beforeAll

doBeforeAll

beforeEach

doBeforeEach

注意

如果您使用 @TestInstance (TestInstance.Lifecycle.PER_METHOD),则 doAfterConstruct 表示每个测试前的回调。这与 All 之前 的不同。

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 扩展控制应用程序的启动和停止。您必须明确告知应用程序停止。
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 生产环境

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

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

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

Expand
回调注解

BeforeEachCallback

@BeforeEach

AfterEachCallback

@AfterEach

AfterAllCallback

@AfterAll

BeforeAllCallback

@BeforeAll

BeforeTestExecutionCallback

 

AfterTestExecutionCallback

 

如需更多信息,请参阅通过 QuarkusTest114 回调文档进行增强

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

© 2025 Red Hat