Skip to content

Commit d91f2eb

Browse files
fix: make NpgsqlDataSource optional in EmbeddingService to allow test isolation
NpgsqlDataSource is an abstract class with no default constructor, so Moq/Castle.DynamicProxy cannot create a proxy for it. Since the upload path (staging-swap) is the only code that needs the data source, and AISearchServiceTests only exercise the search path, making the parameter optional (nullable) with a lazy null check fixes test isolation without weakening production safety.
1 parent d90c7e6 commit d91f2eb

2 files changed

Lines changed: 8 additions & 3 deletions

File tree

EssentialCSharp.Chat.Shared/Services/EmbeddingService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace EssentialCSharp.Chat.Common.Services;
1313
public class EmbeddingService(
1414
VectorStore vectorStore,
1515
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator,
16-
NpgsqlDataSource dataSource)
16+
NpgsqlDataSource? dataSource = null)
1717
{
1818
public static string CollectionName { get; } = "markdown_chunks";
1919

@@ -59,6 +59,10 @@ public async Task GenerateBookContentEmbeddingsAndUploadToVectorStore(
5959
{
6060
collectionName ??= CollectionName;
6161

62+
if (dataSource is null)
63+
throw new InvalidOperationException(
64+
$"{nameof(NpgsqlDataSource)} must be provided to upload embeddings. Ensure it is registered in DI.");
65+
6266
if (!_safeIdentifierRegex.IsMatch(collectionName))
6367
throw new ArgumentException(
6468
$"Collection name '{collectionName}' contains unsafe characters. Use only letters, digits, and underscores.",

EssentialCSharp.Chat.Tests/AISearchServiceTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ private static (AISearchService svc, Mock<VectorStoreCollection<string, BookCont
3333
It.IsAny<CancellationToken>()))
3434
.ReturnsAsync(new GeneratedEmbeddings<Embedding<float>>([new Embedding<float>(new float[1536])]));
3535

36-
var dataSourceMock = new Mock<NpgsqlDataSource>();
37-
var embeddingService = new EmbeddingService(vectorStoreMock.Object, embGenMock.Object, dataSourceMock.Object);
36+
// NpgsqlDataSource has no default constructor so Moq cannot proxy it.
37+
// The upload path is not exercised by these tests, so pass null.
38+
var embeddingService = new EmbeddingService(vectorStoreMock.Object, embGenMock.Object);
3839
var loggerMock = new Mock<ILogger<AISearchService>>();
3940

4041
return (new AISearchService(vectorStoreMock.Object, embeddingService, loggerMock.Object), collectionMock);

0 commit comments

Comments
 (0)