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

fake-ai-services.mddocs/modules/

Fake AI Services Module

Complete overview of the embabel-agent-test-common module providing fake AI services for testing.

Overview

The embabel-agent-test-common module provides fake implementations of AI services for testing without requiring API keys or making real API calls. The primary component is FakeEmbeddingModel, which generates random embeddings for testing embedding-related functionality.

Module Name: embabel-agent-test-common Package: com.embabel.common.test.ai Language: Kotlin (Java-compatible) Framework: Spring AI

What This Module Provides

  • FakeEmbeddingModel - Generates random embeddings without API calls
  • Spring AI Compatibility - Implements EmbeddingModel interface
  • Configurable Dimensions - Support any embedding dimension size
  • Fast Execution - Instant embedding generation for fast tests
  • Zero Dependencies - No API keys or network required

Installation

Add to your Maven pom.xml:

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

Core Component

FakeEmbeddingModel

A fake implementation of Spring AI's EmbeddingModel interface that generates random embeddings.

Features:

  • Implements EmbeddingModel interface
  • Configurable embedding dimensions
  • Generates random float arrays
  • No API calls or network access
  • Fast and deterministic structure (not values)

Usage:

import com.embabel.common.test.ai.FakeEmbeddingModel
import org.springframework.ai.document.Document

// Create with default dimensions (1536)
val model = FakeEmbeddingModel()

// Or with custom dimensions
val model768 = FakeEmbeddingModel(dimensions = 768)

// Generate embeddings
val document = Document("test content")
val embedding = model.embed(document)  // Returns random FloatArray of size 1536

Java Usage:

import com.embabel.common.test.ai.FakeEmbeddingModel;
import org.springframework.ai.document.Document;

FakeEmbeddingModel model = new FakeEmbeddingModel(1536);
Document document = new Document("test content");
float[] embedding = model.embed(document);

Capabilities

Single Document Embedding

Embed individual documents:

val model = FakeEmbeddingModel(dimensions = 512)
val document = Document("Sample text")
val embedding = model.embed(document)
// Returns random 512-dimensional embedding

Batch Embedding

Embed multiple texts at once:

val model = FakeEmbeddingModel()
val texts = listOf("text 1", "text 2", "text 3")
val embeddings = model.embed(texts)
// Returns list of 3 random 1536-dimensional embeddings

EmbeddingRequest Processing

Process Spring AI EmbeddingRequest:

val model = FakeEmbeddingModel(dimensions = 384)
val request = EmbeddingRequest(
    listOf("query 1", "query 2"),
    null
)
val response = model.call(request)
// Returns EmbeddingResponse with 2 random embeddings

What You Can Test

Vector Storage

Test storing and retrieving embeddings:

@Test
fun `test vector storage`() {
    val embeddingModel = FakeEmbeddingModel()
    val vectorStore = SimpleVectorStore(embeddingModel)

    // Add documents with embeddings
    vectorStore.add(listOf(
        Document("doc1"),
        Document("doc2")
    ))

    // Retrieve (structure test, not semantic)
    val docs = vectorStore.getAll()
    assertEquals(2, docs.size)
}

Embedding Pipelines

Test document processing pipelines:

@Test
fun `test embedding pipeline`() {
    val model = FakeEmbeddingModel(dimensions = 768)
    val pipeline = DocumentPipeline(model)

    val documents = listOf(
        Document("doc1"),
        Document("doc2")
    )

    val processed = pipeline.process(documents)

    assertEquals(2, processed.size)
    processed.forEach { doc ->
        assertNotNull(doc.embedding)
        assertEquals(768, doc.embedding!!.size)
    }
}

Search Integration

Test search engine structure (not semantic quality):

@Test
fun `test search engine structure`() {
    val embeddingModel = FakeEmbeddingModel()
    val searchEngine = SemanticSearchEngine(embeddingModel)

    searchEngine.indexDocuments(listOf("doc1", "doc2", "doc3"))

    val results = searchEngine.search("query", topK = 2)

    assertEquals(2, results.size)
    results.forEach { result ->
        assertNotNull(result.document)
        assertTrue(result.score >= 0.0)
    }
}

Service Integration

Test services that use embeddings:

class EmbeddingService(private val embeddingModel: EmbeddingModel) {
    fun embedText(text: String): FloatArray {
        return embeddingModel.embed(Document(text))
    }
}

@Test
fun `test embedding service`() {
    val fakeModel = FakeEmbeddingModel(dimensions = 512)
    val service = EmbeddingService(fakeModel)

    val embedding = service.embedText("test")

    assertEquals(512, embedding.size)
}

Common Dimension Sizes

The module supports any dimension size. Common choices:

ModelDimensionsUse Case
OpenAI ada-0021536Default, general purpose
BERT base768NLP tasks
Sentence transformers384Efficient embeddings
CustomAnyMatch your specific model

Example:

@Test
fun `test with different dimensions`() {
    val model384 = FakeEmbeddingModel(dimensions = 384)
    val model768 = FakeEmbeddingModel(dimensions = 768)
    val model1536 = FakeEmbeddingModel(dimensions = 1536)

    val text = "sample text"
    val doc = Document(text)

    assertEquals(384, model384.embed(doc).size)
    assertEquals(768, model768.embed(doc).size)
    assertEquals(1536, model1536.embed(doc).size)
}

Spring Integration

With TestConfiguration

@SpringBootTest
class EmbeddingIntegrationTest {

    @TestConfiguration
    class TestConfig {
        @Bean
        fun embeddingModel(): EmbeddingModel {
            return FakeEmbeddingModel(dimensions = 768)
        }
    }

    @Autowired
    private lateinit var embeddingModel: EmbeddingModel

    @Test
    fun `test with Spring bean`() {
        val embedding = embeddingModel.embed(Document("test"))
        assertEquals(768, embedding.size)
    }
}

With FakeAiConfiguration

For complete AI test setup, use embabel-agent-test-internal:

@SpringBootTest
@Import(FakeAiConfiguration::class)
class EmbeddingServiceTest {

    @Autowired
    private lateinit var embeddingService: EmbeddingService

    @Test
    fun `test embedding service`() {
        val embedding = embeddingService.embed("test")
        assertEquals(1536, embedding.size)
    }
}

Module Dependencies

This module depends on:

  • embabel-agent-common - Common utilities including random float array generation
  • Spring AI - EmbeddingModel interface and types
  • Kotlin Standard Library - Core Kotlin functionality

All dependencies are transitive.

When to Use This Module

Use this module when:

✓ Testing embedding storage and retrieval ✓ Testing vector database integrations ✓ Testing document processing pipelines ✓ Testing code that uses embeddings without needing real API ✓ Testing with different embedding dimensions ✓ Need fast tests without API calls

Don't use this module when:

✗ Testing semantic similarity quality (embeddings are random) ✗ Testing actual embedding model behavior ✗ Need semantically meaningful results ✗ Testing real-world search relevance ✗ Production use

Important Considerations

Random Embeddings

  • Embeddings are randomly generated, not semantically meaningful
  • Each call generates new random values
  • Not deterministic - same input produces different embeddings each time
  • Suitable for testing structure and flow, NOT semantic quality

What to Test vs Not Test

DO Test:

  • Embedding storage and retrieval mechanisms
  • Vector database integration
  • Document processing workflows
  • Dimension compatibility
  • Error handling in embedding code
  • Batch processing logic
  • API integration structure

DON'T Test:

  • Semantic similarity accuracy
  • Embedding quality or meaningfulness
  • Real-world search relevance
  • Actual model behavior
  • Production performance characteristics

Performance

Fake embeddings are extremely fast:

@Test
fun `test large batch performance`() {
    val model = FakeEmbeddingModel()

    val startTime = System.currentTimeMillis()

    // Embed 10,000 documents instantly
    val texts = (1..10000).map { "Document $it" }
    val embeddings = model.embed(texts)

    val duration = System.currentTimeMillis() - startTime

    assertEquals(10000, embeddings.size)
    println("Embedded 10k documents in ${duration}ms")
}

Comparison with Other Modules

Featureembabel-agent-test-commonembabel-agent-testembabel-agent-test-internal
Fake embeddings✓ Yes✗ No✗ No (uses this module)
LLM stubbing✗ No✓ Yes✗ No
Spring config✗ No✗ No✓ Yes
LanguageKotlinJavaKotlin
FrameworkSpring AIMockitoSpring Boot Test

See also:

  • Integration Testing Module - For LLM stubbing
  • Test Configuration Module - For Spring setup

Complete Example

import com.embabel.common.test.ai.FakeEmbeddingModel
import org.springframework.ai.document.Document
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

class DocumentEmbeddingTest {

    @Test
    fun `test document embedding pipeline`() {
        // Create fake model
        val embeddingModel = FakeEmbeddingModel(dimensions = 768)

        // Create processing service
        val processor = DocumentProcessor(embeddingModel)

        // Process documents
        val documents = listOf(
            Document("First document about AI"),
            Document("Second document about ML"),
            Document("Third document about testing")
        )

        val processedDocs = processor.processDocuments(documents)

        // Assert structure
        assertEquals(3, processedDocs.size)
        processedDocs.forEach { doc ->
            assertNotNull(doc.embedding)
            assertEquals(768, doc.embedding!!.size)
            assertTrue(doc.embedding!!.all { it.isFinite() })
        }
    }

    @Test
    fun `test vector store integration`() {
        val embeddingModel = FakeEmbeddingModel()
        val vectorStore = InMemoryVectorStore(embeddingModel)

        // Add documents
        val doc1 = Document("content1")
        val doc2 = Document("content2")
        vectorStore.add(listOf(doc1, doc2))

        // Verify storage
        val stored = vectorStore.count()
        assertEquals(2, stored)

        // Test retrieval
        val retrieved = vectorStore.getById(doc1.id)
        assertNotNull(retrieved)
        assertNotNull(retrieved.embedding)
        assertEquals(1536, retrieved.embedding!!.size)
    }

    @Test
    fun `test batch embedding performance`() {
        val model = FakeEmbeddingModel()

        // Generate large batch
        val largeBatch = (1..1000).map { "Document $it" }

        val start = System.currentTimeMillis()
        val embeddings = model.embed(largeBatch)
        val duration = System.currentTimeMillis() - start

        assertEquals(1000, embeddings.size)
        assertTrue(duration < 1000, "Should be fast: ${duration}ms")
    }

    @Test
    fun `test different dimension sizes`() {
        val models = mapOf(
            384 to FakeEmbeddingModel(dimensions = 384),
            768 to FakeEmbeddingModel(dimensions = 768),
            1536 to FakeEmbeddingModel(dimensions = 1536)
        )

        models.forEach { (expectedDim, model) ->
            val embedding = model.embed(Document("test"))
            assertEquals(expectedDim, embedding.size,
                "Model should produce ${expectedDim}-dimensional embeddings")
        }
    }
}

Best Practices

  1. Choose Appropriate Dimensions - Match your production model dimensions
  2. Test Structure, Not Semantics - Focus on storage, retrieval, processing
  3. Use for Integration Tests - Test how components work together
  4. Combine with Assertions - Verify embedding dimensions and structure
  5. Performance Test Safely - Use fake embeddings for load testing
  6. Document Limitations - Note that embeddings are random in test docs

Next Steps

Related Modules

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

docs

index.md

tile.json