CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-testing-internal

Internal testing utilities for Quarkus LangChain4j that provide a WiremockAware base class for mocking HTTP-based LLM API calls in integration tests. NOTE: This is an internal-only module not published to Maven Central.

Overview
Eval results
Files

Quarkus LangChain4j Testing Internal

Internal testing utilities for the Quarkus LangChain4j extension ecosystem, providing a streamlined base class that integrates Wiremock mocking capabilities with Quarkus test infrastructure for mocking HTTP-based LLM API calls during testing.

IMPORTANT: This is an internal-only testing module used within the quarkus-langchain4j project. It is NOT published to Maven Central. To use this module, you must build it from source or be working within the quarkus-langchain4j repository.

Package Information

  • Package Name: quarkus-langchain4j-testing-internal
  • Group ID: io.quarkiverse.langchain4j
  • Artifact ID: quarkus-langchain4j-testing-internal
  • Package Type: Maven (Internal Module - Not Published)
  • Language: Java
  • Source Location: https://github.com/quarkiverse/quarkus-langchain4j (testing-internal/ directory)

Building from Source

Since this module is not published to Maven Central, you must build it locally:

git clone https://github.com/quarkiverse/quarkus-langchain4j.git
cd quarkus-langchain4j
git checkout 1.7.4
cd testing-internal
mvn clean install

Installation in Your Project

After building from source, add to your Maven pom.xml:

<dependency>
    <groupId>io.quarkiverse.langchain4j</groupId>
    <artifactId>quarkus-langchain4j-testing-internal</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>

Core Imports

import io.quarkiverse.langchain4j.testing.internal.WiremockAware;

Basic Usage

Extend WiremockAware in your test class to gain access to Wiremock testing utilities:

import io.quarkiverse.langchain4j.testing.internal.WiremockAware;
import io.quarkus.test.QuarkusUnitTest;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.assertj.core.api.Assertions.assertThat;

public class MyLangChainTest extends WiremockAware {

    @RegisterExtension
    static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
        .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
            .addAsResource(new StringAsset(
                "llm.api.url=" + WiremockAware.wiremockUrlForConfig("/v1/chat")
            ), "application.properties"));

    @BeforeEach
    public void setup() {
        // Register mock responses
        wiremock().register(
            post(urlEqualTo("/v1/chat"))
                .willReturn(aResponse()
                    .withHeader("Content-Type", "application/json")
                    .withBody("{\"response\": \"Hello from mock!\"}")
                )
        );
    }

    @Test
    public void testLLMInteraction() {
        // Your test code that calls the LLM API
        // ...

        // Verify the request
        LoggedRequest request = singleLoggedRequest();
        assertThat(request.getUrl()).isEqualTo("/v1/chat");
        assertThat(request.getMethod().toString()).isEqualTo("POST");
    }
}

Capabilities

Configuration URL Generation

Generate Wiremock URL templates for use in test configuration properties before port resolution.

public static String wiremockUrlForConfig()

Returns a Wiremock URL template with port placeholder: "http://localhost:${quarkus.wiremock.devservices.port}". Use this in configuration properties (e.g., application.properties) to reference the Wiremock server before the port is resolved at runtime.

Example:

new StringAsset(
    "my.service.base-url=" + WiremockAware.wiremockUrlForConfig()
)
public static String wiremockUrlForConfig(String path)

Parameters:

  • path (String) - URL path to append to the base URL (with or without leading slash)

Returns: String - Wiremock URL template with the specified path appended

Automatically handles:

  • Empty paths (returns base URL)
  • Missing leading slash (adds it automatically)

Example:

WiremockAware.wiremockUrlForConfig("/api/chat")  // Returns: http://localhost:${...}/api/chat
WiremockAware.wiremockUrlForConfig("api/chat")   // Returns: http://localhost:${...}/api/chat
WiremockAware.wiremockUrlForConfig("")           // Returns: http://localhost:${...}

Runtime URL Resolution

Get fully resolved Wiremock URLs with actual port numbers for use in test methods after Quarkus starts.

public String resolvedWiremockUrl()

Returns the fully resolved Wiremock base URL with actual port number: "http://localhost:<port>". Call this in test methods or lifecycle methods (e.g., @BeforeEach, @AfterEach) after Quarkus has started.

public String resolvedWiremockUrl(String path)

Parameters:

  • path (String) - URL path to append to the base URL (with or without leading slash)

Returns: String - Fully resolved Wiremock URL with the specified path

Automatically handles:

  • Empty paths (returns base URL)
  • Missing leading slash (adds it automatically)

Example:

resolvedWiremockUrl("/api/chat")  // Returns: http://localhost:8080/api/chat (actual port)
resolvedWiremockUrl("api/chat")   // Returns: http://localhost:8080/api/chat
resolvedWiremockUrl("")           // Returns: http://localhost:8080

Wiremock Client Access

Get or create WireMock client instances for stubbing HTTP responses and verifying requests.

protected WireMock wiremock()

Returns a WireMock client instance connected to the resolved Wiremock port. The client is lazily initialized on first call and cached for subsequent calls. Use this client to:

  • Register stub mappings with register()
  • Verify requests with getServeEvents()
  • Reset state with resetRequests() or resetMappings()

Example:

wiremock().register(
    get(urlEqualTo("/api/data"))
        .willReturn(aResponse().withBody("mock data"))
);
protected WireMock wiremock(Integer port)

Parameters:

  • port (Integer) - Specific port number to connect the WireMock client to

Returns: WireMock - WireMock client instance for the specified port

Use this when working with multiple Wiremock instances on different ports.

Port Resolution

Get the actual port number that Wiremock devservices is running on.

protected Integer getResolvedWiremockPort()

Returns the resolved Wiremock devservices port by reading the quarkus.wiremock.devservices.port configuration property value.

State Management

Reset Wiremock state between tests or before verifications.

protected void resetRequests()

Clears all logged requests from Wiremock. Use this to clean up state between test methods or before request verifications to ensure only relevant requests are captured.

Example:

@BeforeEach
public void setup() {
    resetRequests();  // Start with clean slate
    // Register stubs...
}
protected void resetMappings()

Clears all stub mappings from Wiremock. Use this to remove all registered stubs, useful for test cleanup or when you need to completely reconfigure the mock server.

Request Verification

Retrieve and verify logged HTTP requests made to the Wiremock server.

protected LoggedRequest singleLoggedRequest()

Returns: LoggedRequest - The single logged request captured by Wiremock

Retrieves the only logged request and asserts that exactly one request was made. Fails with an AssertJ assertion error if zero or more than one request was logged. The returned LoggedRequest provides access to:

  • Request URL (getUrl())
  • HTTP method (getMethod())
  • Headers (getHeader(String))
  • Request body (getBody(), getBodyAsString())

Example:

LoggedRequest request = singleLoggedRequest();
assertThat(request.getUrl()).isEqualTo("/api/endpoint");
assertThat(request.getMethod().toString()).isEqualTo("POST");
assertThat(request.getHeader("Authorization")).isEqualTo("Bearer token");
protected LoggedRequest singleLoggedRequest(WireMock wireMock)

Parameters:

  • wireMock (WireMock) - Specific WireMock instance to query for logged requests

Returns: LoggedRequest - The single logged request from the specified WireMock instance

Use this variant when working with multiple Wiremock instances to verify requests on a specific instance.

protected byte[] requestBodyOfSingleRequest()

Returns: byte[] - The body bytes of the single logged request

Convenience method that calls singleLoggedRequest() and returns the request body bytes. Useful when you need to verify request body content.

Example:

byte[] body = requestBodyOfSingleRequest();
String bodyString = new String(body, StandardCharsets.UTF_8);
assertThat(bodyString).contains("\"query\":\"test\"");
protected byte[] getRequestBody(ServeEvent serveEvent)

Parameters:

  • serveEvent (ServeEvent) - Wiremock serve event containing the request to extract body from

Returns: byte[] - The request body bytes

Extracts the request body from a serve event. Asserts that the body is not empty before returning. Use this when iterating through multiple serve events.

Example:

List<ServeEvent> events = wiremock().getServeEvents();
for (ServeEvent event : events) {
    byte[] body = getRequestBody(event);
    // Process body...
}

Types

External Types from Dependencies

The following types from external libraries are used in the API:

// From com.github.tomakehurst.wiremock.client
class WireMock {
    void register(MappingBuilder mappingBuilder);
    List<ServeEvent> getServeEvents();
    void resetRequests();
    void resetMappings();
}
// From com.github.tomakehurst.wiremock.verification
class LoggedRequest {
    String getUrl();
    RequestMethod getMethod();
    String getHeader(String key);
    byte[] getBody();
    String getBodyAsString();
}
// From com.github.tomakehurst.wiremock.stubbing
class ServeEvent {
    LoggedRequest getRequest();
}

Integration with Quarkus

This utility class is designed to work with Quarkus test infrastructure:

  • Compatible with @QuarkusTest: Use in integration tests with full Quarkus application context
  • Compatible with QuarkusUnitTest: Use with JUnit 5 extension for more lightweight tests
  • Dev Services Integration: Automatically integrates with Quarkus Wiremock dev services
  • Configuration Property Resolution: Port placeholder ${quarkus.wiremock.devservices.port} is resolved at runtime via MicroProfile Config
  • Quarkus Version: Developed and tested with Quarkus 3.x (part of quarkus-langchain4j-parent 1.7.4)

Design Rationale

This class exists as an alternative to io.quarkiverse.wiremock.devservice.ConnectWireMock which does not work well with QuarkusUnitTest. WiremockAware provides a reliable base class that works consistently across different Quarkus test scenarios.

Dependencies

Tests using this utility require the following dependencies:

<dependencies>
    <!-- Target testing module (must be built from source) -->
    <dependency>
        <groupId>io.quarkiverse.langchain4j</groupId>
        <artifactId>quarkus-langchain4j-testing-internal</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>

    <!-- Quarkus JUnit 5 Internal (provides QuarkusUnitTest and ShrinkWrap) -->
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-junit5-internal</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Wiremock support for Quarkus -->
    <dependency>
        <groupId>io.quarkiverse.wiremock</groupId>
        <artifactId>quarkus-wiremock-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Wiremock standalone -->
    <dependency>
        <groupId>org.wiremock</groupId>
        <artifactId>wiremock-standalone</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- AssertJ for fluent assertions -->
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- JUnit 5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Note: This module is built as part of the quarkus-langchain4j project. Use the Quarkus BOM for version management, and ensure compatibility between Quarkus core and Quarkiverse extensions. The quarkus-junit5-internal dependency provides access to QuarkusUnitTest and ShrinkWrap classes.

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-testing-internal
Workspace
tessl
Visibility
Public
Created
Last updated