Multi-module test support framework for Embabel Agent applications providing integration testing, mock AI services, and test configuration utilities
Complete overview of the embabel-agent-test module for Mockito-based integration testing.
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
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>Abstract base class that provides complete test infrastructure.
Key Features:
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);
}
}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);
}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);
}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();
}Test how agents handle LLM failures:
@Test
void testErrorHandling() {
whenGenerateText(p -> p.contains("error"))
.thenThrow(new RuntimeException("LLM unavailable"));
assertThrows(RuntimeException.class, () -> {
myAgent.processWithError();
});
}Control what the LLM returns:
whenGenerateText(predicate) - Stub text generationwhenCreateObject(predicate, class) - Stub object creationDocumentation:
Assert LLM was called correctly:
verifyGenerateText(predicate) - Verify text generation callverifyCreateObject(predicate, class) - Verify object creation callverifyNoInteractions() - Verify no LLM calls madeverifyNoMoreInteractions() - Verify no additional callsDocumentation:
Inspect actual call parameters:
capturePrompt() - Capture prompt stringscaptureLlmInteraction() - Capture interaction detailscaptureOutputClass() - Capture output class typesDocumentation:
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 agentsLlmOperations - Intercepted LLM callsModelProvider - No real models neededThis module depends on:
All dependencies are transitive - you only need to add embabel-agent-test.
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
| Feature | embabel-agent-test | embabel-agent-test-common | embabel-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 |
| Language | Java | Kotlin | Kotlin |
See also:
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);
}
}verifyNoMoreInteractions() when appropriate