CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-test-support

Multi-module test support framework for Embabel Agent applications providing integration testing, mock AI services, and test configuration utilities

Overview
Eval results
Files

integration-testing.mddocs/modules/

Integration Testing Module

Complete overview of the embabel-agent-test module for Mockito-based integration testing.

Overview

The embabel-agent-test module provides Mockito-based integration testing support for Embabel Agent applications. It enables writing integration tests that mock LLM operations, allowing you to test agent behavior without making actual API calls.

Module Name: embabel-agent-test Package: com.embabel.agent.test.integration Language: Java Test Framework: JUnit 5 + Mockito

What This Module Provides

  • EmbabelMockitoIntegrationTest - Abstract base class with Spring Boot test context
  • Stubbing Methods - Control what LLM returns in tests
  • Verification Methods - Assert LLM was called correctly
  • Argument Capture - Inspect actual LLM call parameters
  • No API Calls - All LLM operations are mocked

Installation

Add to your Maven pom.xml:

<dependency>
    <groupId>com.embabel.agent</groupId>
    <artifactId>embabel-agent-test</artifactId>
    <version>0.3.3</version>
    <scope>test</scope>
</dependency>

Core Component

EmbabelMockitoIntegrationTest

Abstract base class that provides complete test infrastructure.

Key Features:

  • Spring Boot test context with @SpringBootTest
  • Mocked LLM operations via @MockitoBean
  • Helper methods for stubbing and verification
  • Access to AgentPlatform for running agents

Usage:

import com.embabel.agent.test.integration.EmbabelMockitoIntegrationTest;
import org.junit.jupiter.api.Test;

public class MyAgentTest extends EmbabelMockitoIntegrationTest {

    @Test
    void testMyAgent() {
        // Stub LLM
        whenGenerateText(p -> p.contains("hello")).thenReturn("Hello!");

        // Test your agent
        String result = myAgent.greet();

        // Verify and assert
        verifyGenerateText(p -> p.contains("hello"));
        assertEquals("Hello!", result);
    }
}

What You Can Test

Text Generation

Test agents that generate text responses from LLM:

@Test
void testTextGeneration() {
    whenGenerateText(p -> p.contains("summarize"))
        .thenReturn("This is a summary");

    String result = myAgent.summarize(document);

    verifyGenerateText(p -> p.contains("summarize"));
    assertEquals("This is a summary", result);
}

Object Creation

Test agents that create structured objects from LLM:

@Test
void testObjectCreation() {
    Person expected = new Person("Alice", 30);

    whenCreateObject(p -> p.contains("extract"), Person.class)
        .thenReturn(expected);

    Person result = myAgent.extractPerson(text);

    verifyCreateObject(p -> p.contains("extract"), Person.class);
    assertEquals(expected, result);
}

Multi-Step Workflows

Test agents that make multiple LLM calls:

@Test
void testMultiStep() {
    whenGenerateText(p -> p.contains("step1")).thenReturn("Result 1");
    whenGenerateText(p -> p.contains("step2")).thenReturn("Result 2");

    myAgent.multiStepProcess();

    verifyGenerateText(p -> p.contains("step1"));
    verifyGenerateText(p -> p.contains("step2"));
    verifyNoMoreInteractions();
}

Error Handling

Test how agents handle LLM failures:

@Test
void testErrorHandling() {
    whenGenerateText(p -> p.contains("error"))
        .thenThrow(new RuntimeException("LLM unavailable"));

    assertThrows(RuntimeException.class, () -> {
        myAgent.processWithError();
    });
}

Capabilities

Stubbing

Control what the LLM returns:

  • whenGenerateText(predicate) - Stub text generation
  • whenCreateObject(predicate, class) - Stub object creation
  • Support for interaction matching (model, temperature, etc.)

Documentation:

  • Stubbing API
  • Stubbing Guide

Verification

Assert LLM was called correctly:

  • verifyGenerateText(predicate) - Verify text generation call
  • verifyCreateObject(predicate, class) - Verify object creation call
  • verifyNoInteractions() - Verify no LLM calls made
  • verifyNoMoreInteractions() - Verify no additional calls

Documentation:

Argument Capture

Inspect actual call parameters:

  • capturePrompt() - Capture prompt strings
  • captureLlmInteraction() - Capture interaction details
  • captureOutputClass() - Capture output class types

Documentation:

Integration with Spring Boot

The module integrates seamlessly with Spring Boot:

@SpringBootTest
public class MyAgentTest extends EmbabelMockitoIntegrationTest {

    @Autowired
    private MyService myService;

    @Autowired
    protected AgentPlatform agentPlatform;

    @Test
    void testServiceIntegration() {
        whenGenerateText(p -> true).thenReturn("result");

        String result = myService.process("input");

        assertNotNull(result);
    }
}

Provided Components:

  • AgentPlatform - For running agents
  • Mocked LlmOperations - Intercepted LLM calls
  • Mocked ModelProvider - No real models needed
  • Spring application context - Full dependency injection

Module Dependencies

This module depends on:

  • embabel-agent-api - Core agent interfaces
  • Spring Boot Test - Test framework
  • Mockito - Mocking library
  • JUnit 5 - Test runner

All dependencies are transitive - you only need to add embabel-agent-test.

When to Use This Module

Use this module when:

✓ Writing integration tests for agent applications ✓ Need to mock LLM operations ✓ Want to verify agent behavior without API calls ✓ Testing prompt construction and LLM interaction ✓ Need fast, repeatable tests without API costs

Don't use this module when:

✗ Testing simple utility functions (use unit tests) ✗ Need real LLM responses for quality testing ✗ Only testing non-LLM code ✗ Already have a different mocking strategy

Comparison with Other Modules

Featureembabel-agent-testembabel-agent-test-commonembabel-agent-test-internal
Mockito stubs✓ Yes✗ No✗ No
LLM verification✓ Yes✗ No✗ No
Fake embeddings✗ No✓ Yes✓ Yes (via config)
Spring config✗ No✗ No✓ Yes
LanguageJavaKotlinKotlin

See also:

Complete Example

import com.embabel.agent.test.integration.EmbabelMockitoIntegrationTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
public class DocumentAnalyzerTest extends EmbabelMockitoIntegrationTest {

    @Autowired
    private DocumentAnalyzer analyzer;

    @Test
    void testDocumentSummarization() {
        // Stub the LLM to return a summary
        whenGenerateText(prompt ->
            prompt.contains("summarize") &&
            prompt.contains("document")
        ).thenReturn("Document summary");

        // Execute analyzer
        String summary = analyzer.summarize(testDocument);

        // Verify LLM was called correctly
        verifyGenerateText(prompt ->
            prompt.contains("summarize") &&
            prompt.contains(testDocument.getTitle())
        );

        // Assert result
        assertEquals("Document summary", summary);
        assertNotNull(summary);
    }

    @Test
    void testKeywordExtraction() {
        // Create expected keywords object
        Keywords expected = new Keywords(
            List.of("AI", "machine learning", "testing")
        );

        // Stub object creation
        whenCreateObject(
            prompt -> prompt.contains("extract keywords"),
            Keywords.class
        ).thenReturn(expected);

        // Execute extraction
        Keywords result = analyzer.extractKeywords(testDocument);

        // Verify
        verifyCreateObject(
            prompt -> prompt.contains("extract keywords"),
            Keywords.class
        );

        // Assert
        assertEquals(expected, result);
        assertEquals(3, result.getKeywords().size());
    }

    @Test
    void testAnalysisWorkflow() {
        // Stub multiple operations
        whenGenerateText(p -> p.contains("analyze tone"))
            .thenReturn("Professional");
        whenCreateObject(p -> p.contains("extract entities"), Entities.class)
            .thenReturn(new Entities(List.of("Company A", "Product X")));

        // Execute full workflow
        AnalysisResult result = analyzer.analyzeDocument(testDocument);

        // Verify all operations
        verifyGenerateText(p -> p.contains("analyze tone"));
        verifyCreateObject(p -> p.contains("extract entities"), Entities.class);
        verifyNoMoreInteractions();

        // Assert complete result
        assertNotNull(result);
        assertEquals("Professional", result.getTone());
        assertEquals(2, result.getEntities().size());
    }

    @Test
    void testCachedPath() {
        // Execute cached operation
        String cached = analyzer.getCachedSummary(documentId);

        // Verify no LLM calls made
        verifyNoInteractions();

        // Assert cached value
        assertNotNull(cached);
    }
}

Best Practices

  1. Extend EmbabelMockitoIntegrationTest - Always extend this base class
  2. Stub Before Execute - Set up stubs before running code
  3. Verify After Execute - Always verify LLM was called correctly
  4. Use Specific Predicates - Match exact prompts, not just "any"
  5. Test Error Cases - Include tests for LLM failures
  6. Verify No Extra Calls - Use verifyNoMoreInteractions() when appropriate
  7. Combine with Assertions - Verify LLM calls AND assert results

Next Steps

Related Modules

tessl i tessl/maven-com-embabel-agent--embabel-agent-test-support@0.3.0

docs

index.md

tile.json