Testing LangChain4j-applikasjoner

March 2, 2026 · View on GitHub

Innholdsfortegnelse

Denne guiden går gjennom testene som demonstrerer hvordan man tester AI-applikasjoner uten å kreve API-nøkler eller eksterne tjenester.

Rask start

Kjør alle tester med en enkelt kommando:

Bash:

mvn test

PowerShell:

mvn --% test

Når alle testene er bestått, bør du se output som skjermbildet under — tester kjører uten feil.

Successful Test Results

Vellykket testruting som viser at alle tester passerer uten feil

Hva testene dekker

Dette kurset fokuserer på enhetstester som kjører lokalt. Hver test demonstrerer et spesifikt LangChain4j-konsept isolert. Testpyramiden under viser hvor enhetstester passer inn — de utgjør det raske og pålitelige fundamentet som resten av teststrategien bygger på.

Testing Pyramid

Testpyramide som viser balansen mellom enhetstester (raskt, isolert), integrasjonstester (ekte komponenter) og ende-til-ende-tester. Dette kurset dekker enhetstesting.

ModulTesterFokusNøkkelfiler
00 - Rask start6Promptmaler og variabelsubstitusjonSimpleQuickStartTest.java
01 - Introduksjon8Samtalehukommelse og tilstandsstyrt chatSimpleConversationTest.java
02 - Prompt Engineering12GPT-5.2-mønstre, ivrighetsnivåer, strukturert outputSimpleGpt5PromptTest.java
03 - RAG10Dokumentinngestion, innebygging, likhetssøkDocumentServiceTest.java
04 - Verktøy12Funksjonskalling og verktøykjederSimpleToolsTest.java
05 - MCP8Model Context Protocol med Stdio-transportSimpleMcpTest.java

Kjøre testene

Kjør alle tester fra rotmappen:

Bash:

mvn test

PowerShell:

mvn --% test

Kjør tester for en bestemt modul:

Bash:

cd 01-introduction && mvn test
# Eller fra rot
mvn test -pl 01-introduction

PowerShell:

cd 01-introduction; mvn --% test
# Eller fra rot
mvn --% test -pl 01-introduction

Kjør en enkelt testklasse:

Bash:

mvn test -Dtest=SimpleConversationTest

PowerShell:

mvn --% test -Dtest=SimpleConversationTest

Kjør en spesifikk testmetode:

Bash:

mvn test -Dtest=SimpleConversationTest#børBeholdeSamtalehistorikk

PowerShell:

mvn --% test -Dtest=SimpleConversationTest#børOpprettholdeSamtalehistorikk

Kjøre tester i VS Code

Hvis du bruker Visual Studio Code, gir Test Explorer et grafisk grensesnitt for å kjøre og feilsøke tester.

VS Code Test Explorer

VS Code Test Explorer som viser testtreet med alle Java testklasser og individuelle testmetoder

For å kjøre tester i VS Code:

  1. Åpne Test Explorer ved å klikke på kolbeikonet i aktivitetslinjen
  2. Utvid testtreet for å se alle moduler og testklasser
  3. Klikk på avspillingsknappen ved siden av en test for å kjøre den individuelt
  4. Klikk "Run All Tests" for å kjøre hele settet
  5. Høyreklikk på en test og velg "Debug Test" for å sette brytepunkter og trinnvise kjøringer

Test Explorer viser grønne avkrysningsmerker for beståtte tester og gir detaljerte feilmeldinger ved testfeil.

Testingmønstre

Mønster 1: Testing av promptmaler

Det enkleste mønsteret tester promptmaler uten å kalle noen AI-modell. Du verifiserer at variabelsubstitusjon fungerer korrekt og at prompts formateres som forventet.

Prompt Template Testing

Testing av promptmaler som viser flyten: mal med plassholdere → verdier anvendt → formatert output verifisert

@Test
@DisplayName("Should format prompt template with variables")
void testPromptTemplateFormatting() {
    PromptTemplate template = PromptTemplate.from(
        "Best time to visit {{destination}} for {{activity}}?"
    );
    
    Prompt prompt = template.apply(Map.of(
        "destination", "Paris",
        "activity", "sightseeing"
    ));
    
    assertThat(prompt.text()).isEqualTo("Best time to visit Paris for sightseeing?");
}

Denne testen ligger i 00-quick-start/src/test/java/com/example/langchain4j/quickstart/SimpleQuickStartTest.java.

Kjør den:

Bash:

cd 00-quick-start && mvn test -Dtest=SimpleQuickStartTest#testPromptMalFormatering

PowerShell:

cd 00-quick-start; mvn --% test -Dtest=SimpleQuickStartTest#testPromptMalingsformatering

Mønster 2: Mocking av språkmodeller

Når man tester samtalelogikk, bruk Mockito for å lage falske modeller som returnerer forhåndsbestemte svar. Dette gjør testene raske, gratis og deterministiske.

Mock vs Real API Comparison

Sammenligning som viser hvorfor mocks foretrekkes for testing: de er raske, gratis, deterministiske og krever ingen API-nøkler

@ExtendWith(MockitoExtension.class)
class SimpleConversationTest {
    
    private ConversationService conversationService;
    
    @Mock
    private OpenAiOfficialChatModel mockChatModel;
    
    @BeforeEach
    void setUp() {
        ChatResponse mockResponse = ChatResponse.builder()
            .aiMessage(AiMessage.from("This is a test response"))
            .build();
        when(mockChatModel.chat(anyList())).thenReturn(mockResponse);
        
        conversationService = new ConversationService(mockChatModel);
    }
    
    @Test
    void shouldMaintainConversationHistory() {
        String conversationId = conversationService.startConversation();
        
        ChatResponse mockResponse1 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 1"))
            .build();
        ChatResponse mockResponse2 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 2"))
            .build();
        ChatResponse mockResponse3 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 3"))
            .build();
        
        when(mockChatModel.chat(anyList()))
            .thenReturn(mockResponse1)
            .thenReturn(mockResponse2)
            .thenReturn(mockResponse3);

        conversationService.chat(conversationId, "First message");
        conversationService.chat(conversationId, "Second message");
        conversationService.chat(conversationId, "Third message");

        List<ChatMessage> history = conversationService.getHistory(conversationId);
        assertThat(history).hasSize(6); // 3 bruker + 3 AI-meldinger
    }
}

Dette mønsteret finnes i 01-introduction/src/test/java/com/example/langchain4j/service/SimpleConversationTest.java. Mocken sikrer konsekvent oppførsel slik at du kan verifisere at hukommelsesadministrasjon fungerer riktig.

Mønster 3: Testing av samtaleisolasjon

Samtalehukommelsen må holde flere brukere adskilt. Denne testen verifiserer at samtaler ikke blander sammen kontekster.

Conversation Isolation

Testing av samtaleisolasjon som viser separate hukommelseslagre for ulike brukere for å hindre kontekstblanding

@Test
void shouldIsolateConversationsByid() {
    String conv1 = conversationService.startConversation();
    String conv2 = conversationService.startConversation();
    
    ChatResponse mockResponse = ChatResponse.builder()
        .aiMessage(AiMessage.from("Response"))
        .build();
    when(mockChatModel.chat(anyList())).thenReturn(mockResponse);

    conversationService.chat(conv1, "Message for conversation 1");
    conversationService.chat(conv2, "Message for conversation 2");

    List<ChatMessage> history1 = conversationService.getHistory(conv1);
    List<ChatMessage> history2 = conversationService.getHistory(conv2);
    
    assertThat(history1).hasSize(2);
    assertThat(history2).hasSize(2);
}

Hver samtale opprettholder sin egen uavhengige historikk. I produksjonssystemer er denne isolasjonen kritisk for multi-brukerapplikasjoner.

Mønster 4: Testing av verktøy uavhengig

Verktøy er funksjoner AI kan kalle. Test dem direkte for å sikre at de fungerer riktig uavhengig av AI-beslutninger.

Tools Testing

Testing av verktøy uavhengig ved å vise kjøring av mock-verktøy uten AI-kall for å verifisere forretningslogikk

@Test
void shouldConvertCelsiusToFahrenheit() {
    TemperatureTool tempTool = new TemperatureTool();
    String result = tempTool.celsiusToFahrenheit(25.0);
    assertThat(result).containsPattern("77[.,]0°F");
}

@Test
void shouldDemonstrateToolChaining() {
    WeatherTool weatherTool = new WeatherTool();
    TemperatureTool tempTool = new TemperatureTool();

    String weatherResult = weatherTool.getCurrentWeather("Seattle");
    assertThat(weatherResult).containsPattern("\\d+°C");

    String conversionResult = tempTool.celsiusToFahrenheit(22.0);
    assertThat(conversionResult).containsPattern("71[.,]6°F");
}

Disse testene fra 04-tools/src/test/java/com/example/langchain4j/agents/tools/SimpleToolsTest.java validerer verktøylogikk uten AI-involvering. Kjedereferanseeksempelet viser hvordan output fra ett verktøy mates inn i input til et annet.

Mønster 5: I-minnet RAG-testing

RAG-systemer krever tradisjonelt vektordatabaser og embeddingtjenester. I-minnet-mønsteret lar deg teste hele pipeline uten eksterne avhengigheter.

In-Memory RAG Testing

I-minnet RAG testflyt som viser dokumentparsing, embeddinglagring og likhetssøk uten krav til database

@Test
void testProcessTextDocument() {
    String content = "This is a test document.\nIt has multiple lines.";
    InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
    
    DocumentService.ProcessedDocument result = 
        documentService.processDocument(inputStream, "test.txt");

    assertNotNull(result);
    assertTrue(result.segments().size() > 0);
    assertEquals("test.txt", result.segments().get(0).metadata().getString("filename"));
}

Denne testen fra 03-rag/src/test/java/com/example/langchain4j/rag/service/DocumentServiceTest.java oppretter et dokument i minnet og verifiserer chunking og metadatahåndtering.

Mønster 6: MCP-integrasjonstesting

MCP-modulen tester Model Context Protocol-integrasjon ved å bruke stdio-transport. Disse testene verifiserer at applikasjonen din kan starte og kommunisere med MCP-servere som underprosesser.

Testene i 05-mcp/src/test/java/com/example/langchain4j/mcp/SimpleMcpTest.java validerer MCP-klientatferd.

Kjør dem:

Bash:

cd 05-mcp && mvn test

PowerShell:

cd 05-mcp; mvn --% test

Testingsfilosofi

Test koden din, ikke AI-en. Testene dine skal validere koden du skriver ved å sjekke hvordan prompts konstrueres, hvordan hukommelsen administreres, og hvordan verktøy utføres. AI-svar varierer og bør ikke være del av testassertioner. Spør deg om promptmalen riktig erstatter variabler, ikke om AI gir det riktige svaret.

Bruk mocks for språkmodeller. De er eksterne avhengigheter som er trege, kostbare og ikke-deterministiske. Mocking gjør tester raske med millisekunder i stedet for sekunder, gratis uten API-kostnader, og deterministiske med samme resultat hver gang.

Hold tester uavhengige. Hver test bør sette opp sine egne data, ikke stole på andre tester, og rydde opp etter seg. Tester skal passere uavhengig av kjørerekkefølge.

Test kanttilfeller utover den glade stien. Prøv tomme input, veldig store input, spesialtegn, ugyldige parametere og grenseverdier. Disse avslører ofte feil som vanlig bruk ikke eksponerer.

Bruk beskrivende navn. Sammenlign shouldMaintainConversationHistoryAcrossMultipleMessages() med test1(). Det førstnevnte forteller deg eksakt hva som testes, noe som gjør feilsøking mye enklere.

Neste steg

Nå som du forstår testingmønstrene, dykk dypere inn i hver modul:

Hver moduls README gir detaljerte forklaringer av konseptene som testes her.


Navigasjon: ← Tilbake til hovedsiden


Ansvarsfraskrivelse: Dette dokumentet er oversatt ved hjelp av AI-oversettelsestjenesten Co-op Translator. Selv om vi streber etter nøyaktighet, vennligst vær oppmerksom på at automatiske oversettelser kan inneholde feil eller unøyaktigheter. Det opprinnelige dokumentet på originalspråket bør betraktes som den autoritative kilden. For kritisk informasjon anbefales profesjonell menneskelig oversettelse. Vi er ikke ansvarlige for misforståelser eller feiltolkninger som oppstår ved bruk av denne oversettelsen.