Multi-module test support framework for Embabel Agent applications providing integration testing, mock AI services, and test configuration utilities
Complete API reference for verifying LLM operations in tests.
Verification methods assert that the mocked LLM was called with expected parameters. Use these to verify your code interacts with the LLM correctly.
Module: embabel-agent-test
Class: EmbabelMockitoIntegrationTest
Import: import com.embabel.agent.test.integration.EmbabelMockitoIntegrationTest;
Verify LLM text generation with prompt matching.
protected void verifyGenerateText(
Predicate<String> promptMatcher
)Parameters:
promptMatcher - Predicate to match against the prompt textThrows: AssertionError if verification fails
Usage:
verifyGenerateText(prompt -> prompt.contains("summarize"));When to use: Most common case - verify based on prompt content only.
Verify LLM text generation with both prompt and interaction matching.
protected void verifyGenerateText(
Predicate<String> promptMatcher,
Predicate<LlmInteraction> llmInteractionMatcher
)Parameters:
promptMatcher - Predicate to match against the prompt textllmInteractionMatcher - Predicate to match LlmInteraction detailsThrows: AssertionError if verification fails
Usage:
verifyGenerateText(
prompt -> prompt.contains("analyze"),
interaction -> interaction.getModel().equals("gpt-4")
);When to use: When you need to verify both prompt and model configuration.
Verify text generation with prompt matching (alternative signature).
protected void verifyGenerateTextMatching(
Predicate<String> promptMatcher
)Parameters:
promptMatcher - Predicate to match against the prompt textThrows: AssertionError if verification fails
Usage:
verifyGenerateTextMatching(prompt -> prompt.startsWith("Generate"));When to use: Alternative to verifyGenerateText with same functionality.
Verify text generation with specific LlmInteraction instance.
protected void verifyGenerateTextMatching(
Predicate<String> promptMatcher,
LlmInteraction llmInteraction
)Parameters:
promptMatcher - Predicate to match against the prompt textllmInteraction - Expected LlmInteraction instanceThrows: AssertionError if verification fails
Usage:
LlmInteraction expectedInteraction = new LlmInteraction(...);
verifyGenerateTextMatching(
prompt -> prompt.contains("text"),
expectedInteraction
);When to use: When you have a specific interaction instance to match against.
Verify LLM object creation with prompt and class matching.
protected <T> void verifyCreateObject(
Predicate<String> promptMatcher,
Class<T> outputClass
)Type Parameters:
T - The type of object being createdParameters:
promptMatcher - Predicate to match against the prompt textoutputClass - Expected output class typeThrows: AssertionError if verification fails
Usage:
verifyCreateObject(
prompt -> prompt.contains("extract"),
Person.class
);When to use: Most common case - verify based on prompt and output type.
Verify LLM object creation with prompt, class, and interaction matching.
protected <T> void verifyCreateObject(
Predicate<String> promptMatcher,
Class<T> outputClass,
Predicate<LlmInteraction> llmInteractionMatcher
)Type Parameters:
T - The type of object being createdParameters:
promptMatcher - Predicate to match against the prompt textoutputClass - Expected output class typellmInteractionMatcher - Predicate to match LlmInteraction detailsThrows: AssertionError if verification fails
Usage:
verifyCreateObject(
prompt -> prompt.contains("extract"),
Person.class,
interaction -> interaction.getTemperature() == 0.0
);When to use: When you need to verify prompt, type, and model configuration.
Verify object creation with custom ArgumentMatcher for complex validation.
protected <T> void verifyCreateObjectMatching(
Predicate<String> promptMatcher,
Class<T> outputClass,
ArgumentMatcher<LlmInteraction> llmInteractionMatcher
)Type Parameters:
T - The type of object being createdParameters:
promptMatcher - Predicate to match against the prompt textoutputClass - Expected output class typellmInteractionMatcher - ArgumentMatcher for complex LlmInteraction validationThrows: AssertionError if verification fails
Usage:
verifyCreateObjectMatching(
prompt -> prompt.contains("data"),
DataObject.class,
interaction -> interaction.getToolGroups().size() > 2
);When to use: When you need complex validation logic for interactions.
Verify object creation with message list matching.
protected <T> void verifyCreateObjectMatchingMessages(
ArgumentMatcher<List<Message>> promptMatcher,
Class<T> outputClass,
ArgumentMatcher<LlmInteraction> llmInteractionMatcher
)Type Parameters:
T - The type of object being createdParameters:
promptMatcher - ArgumentMatcher for matching message listsoutputClass - Expected output class typellmInteractionMatcher - ArgumentMatcher for LlmInteraction validationThrows: AssertionError if verification fails
Usage:
verifyCreateObjectMatchingMessages(
messages -> messages.size() == 1 && messages.get(0).getRole().equals("user"),
Result.class,
interaction -> interaction.getModel().startsWith("gpt")
);When to use: When you need to verify the complete message structure.
Verify that no interactions occurred with the mocked LLM.
protected void verifyNoInteractions()Throws: AssertionError if any interactions occurred
Usage:
verifyNoInteractions();When to use: To verify code path didn't use LLM (e.g., cached results).
Verify that no additional interactions occurred beyond already verified ones.
protected void verifyNoMoreInteractions()Throws: AssertionError if unverified interactions exist
Usage:
verifyGenerateText(p -> p.contains("test"));
verifyNoMoreInteractions();When to use: To ensure no unexpected LLM calls were made.
Create an ArgumentCaptor for capturing prompt strings.
protected ArgumentCaptor<String> capturePrompt()Returns: ArgumentCaptor<String> for capturing prompts
Usage:
ArgumentCaptor<String> captor = capturePrompt();
verify(llmOperations).generateText(captor.capture(), any());
String capturedPrompt = captor.getValue();
assertTrue(capturedPrompt.contains("expected"));When to use: When you need to inspect the actual prompt text.
Create an ArgumentCaptor for capturing LlmInteraction instances.
protected ArgumentCaptor<LlmInteraction> captureLlmInteraction()Returns: ArgumentCaptor<LlmInteraction> for capturing interactions
Usage:
ArgumentCaptor<LlmInteraction> captor = captureLlmInteraction();
// ... perform verification ...
LlmInteraction interaction = captor.getValue();
assertEquals("gpt-4", interaction.getModel());
assertEquals(0.7, interaction.getTemperature());When to use: When you need to inspect interaction details.
Create an ArgumentCaptor for capturing output class types.
protected <T> ArgumentCaptor<Class<T>> captureOutputClass()Type Parameters:
T - The type of class being capturedReturns: ArgumentCaptor<Class<T>> for capturing class types
Usage:
ArgumentCaptor<Class<?>> captor = captureOutputClass();
// ... perform verification ...
Class<?> capturedClass = captor.getValue();
assertEquals(Person.class, capturedClass);When to use: When you need to verify the output class type.
@Test
void testSimpleVerification() {
myAgent.process("input");
verifyGenerateText(prompt -> prompt.contains("input"));
}@Test
void testMultipleCalls() {
myAgent.multiStep();
verifyGenerateText(p -> p.contains("step1"));
verifyGenerateText(p -> p.contains("step2"));
verifyNoMoreInteractions();
}@Test
void testWithInteraction() {
myAgent.preciseAnalysis();
verifyGenerateText(
p -> p.contains("analyze"),
i -> i.getModel().equals("gpt-4") && i.getTemperature() == 0.0
);
}@Test
void testObjectCreation() {
myAgent.extractData();
verifyCreateObject(
p -> p.contains("extract"),
Person.class
);
}@Test
void testCapture() {
myAgent.process("test input");
ArgumentCaptor<LlmInteraction> captor = captureLlmInteraction();
verifyGenerateText(p -> true);
LlmInteraction interaction = captor.getValue();
assertEquals("gpt-4", interaction.getModel());
assertTrue(interaction.getMaxTokens() > 0);
}@Test
void testCachedPath() {
myAgent.getCached();
verifyNoInteractions();
}@Test
void testComplexPredicate() {
myAgent.complexOperation();
verifyGenerateText(prompt ->
prompt.contains("analyze") &&
prompt.length() > 50 &&
prompt.toLowerCase().contains("data")
);
}Mockito provides verification modes that can be used with these methods:
import static org.mockito.Mockito.*;
// Verify called exactly once (default)
verifyGenerateText(p -> true);
// Verify called N times
verify(llmOperations, times(2)).generateText(any(), any());
// Verify never called
verify(llmOperations, never()).generateText(any(), any());
// Verify called at least once
verify(llmOperations, atLeastOnce()).generateText(any(), any());
// Verify called at most N times
verify(llmOperations, atMost(3)).generateText(any(), any());Note: For direct Mockito verification on llmOperations, you'll need to import Mockito's verify and use argThat() with predicates.
@FunctionalInterface
interface Predicate<T> {
boolean test(T t);
}Functional interface for matching conditions.
class ArgumentCaptor<T> {
T getValue();
List<T> getAllValues();
}Mockito utility for capturing arguments.
@FunctionalInterface
interface ArgumentMatcher<T> {
boolean matches(T argument);
}Custom argument matching interface.
class LlmInteraction {
String getModel();
Double getTemperature();
Integer getMaxTokens();
List<String> getToolGroups();
}Configuration for LLM interaction.
interface Message {
String getContent();
String getRole();
}Chat message interface.