// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Moq;
namespace Microsoft.Agents.AI.UnitTests;
///
/// Unit tests for the class.
///
public sealed class AIAgentBuilderExtensionsTests
{
private readonly Mock _chatClientMock;
private readonly TestAIAgent _innerAgent;
public AIAgentBuilderExtensionsTests()
{
this._chatClientMock = new Mock();
this._innerAgent = new TestAIAgent();
this._chatClientMock
.Setup(c => c.GetResponseAsync(
It.IsAny>(),
It.IsAny(),
It.IsAny()))
.ReturnsAsync(new ChatResponse([new ChatMessage(ChatRole.Assistant, "{\"result\": \"test\"}")]));
}
[Fact]
public void UseStructuredOutput_WithNullBuilder_ThrowsArgumentNullException()
{
// Arrange
AIAgentBuilder builder = null!;
// Act & Assert
Assert.Throws("builder", () =>
builder.UseStructuredOutput(this._chatClientMock.Object));
}
[Fact]
public void UseStructuredOutput_WithExplicitChatClient_BuildsStructuredOutputAgent()
{
// Arrange
AIAgentBuilder builder = this._innerAgent.AsBuilder();
// Act
AIAgent agent = builder.UseStructuredOutput(this._chatClientMock.Object).Build();
// Assert
Assert.IsType(agent);
}
[Fact]
public void UseStructuredOutput_WithNoChatClientParameter_ResolvesChatClientFromServices()
{
// Arrange
ServiceCollection services = new();
services.AddSingleton(this._chatClientMock.Object);
ServiceProvider serviceProvider = services.BuildServiceProvider();
AIAgentBuilder builder = this._innerAgent.AsBuilder();
// Act
AIAgent agent = builder.UseStructuredOutput().Build(serviceProvider);
// Assert
Assert.IsType(agent);
}
[Fact]
public void UseStructuredOutput_WithNoChatClientAvailable_ThrowsInvalidOperationException()
{
// Arrange
AIAgentBuilder builder = this._innerAgent.AsBuilder();
// Act & Assert
InvalidOperationException exception = Assert.Throws(() =>
builder.UseStructuredOutput().Build(services: null));
Assert.Contains("IChatClient", exception.Message);
}
[Fact]
public void UseStructuredOutput_WithOptionsFactory_AppliesConfiguration()
{
// Arrange
AIAgentBuilder builder = this._innerAgent.AsBuilder();
bool factoryInvoked = false;
// Act
AIAgent agent = builder.UseStructuredOutput(
this._chatClientMock.Object,
() =>
{
factoryInvoked = true;
return new StructuredOutputAgentOptions
{
ChatClientSystemMessage = "Custom system message"
};
}).Build();
// Assert
Assert.True(factoryInvoked);
Assert.IsType(agent);
}
}