Skip to content

refactor: remove FluentAssertions #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" Version="9.5.0"/>
<PackageReference Include="Microsoft.Extensions.AI" Version="9.7.0" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="JsonSchema.Net.Generation" Version="5.0.3" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.5.0" />
<PackageReference Include="JsonSchema.Net.Generation" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.7.0" />
</ItemGroup>

</Project>
11 changes: 5 additions & 6 deletions test/Cnblogs.DashScope.AI.UnitTests/ChatClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Text;
using Cnblogs.DashScope.Core;
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;

using Microsoft.Extensions.AI;
using NSubstitute;
using NSubstitute.Extensions;
Expand Down Expand Up @@ -46,7 +46,7 @@ public async Task ChatClient_TextCompletion_SuccessAsync()
Arg.Is<ModelRequest<TextGenerationInput, ITextGenerationParameters>>(
m => m.IsEquivalent(testCase.RequestModel)),
Arg.Any<CancellationToken>());
response.Messages[0].Text.Should().Be(testCase.ResponseModel.Output.Choices?.First().Message.Content);
Assert.Equal(testCase.ResponseModel.Output.Choices![0].Message.Content, response.Messages[0].Text);
}

[Fact]
Expand Down Expand Up @@ -93,7 +93,7 @@ public async Task ChatClient_TextCompletionStream_SuccessAsync()
Arg.Is<ModelRequest<TextGenerationInput, ITextGenerationParameters>>(
m => m.IsEquivalent(testCase.RequestModel)),
Arg.Any<CancellationToken>());
text.ToString().Should().Be(testCase.ResponseModel.Output.Choices?.First().Message.Content);
Assert.Equal(testCase.ResponseModel.Output.Choices![0].Message.Content, text.ToString());
}

[Fact]
Expand Down Expand Up @@ -139,8 +139,7 @@ public async Task ChatClient_ImageRecognition_SuccessAsync()
await dashScopeClient.Received().GetMultimodalGenerationAsync(
Arg.Is<ModelRequest<MultimodalInput, IMultimodalParameters>>(m => m.IsEquivalent(testCase.RequestModel)),
Arg.Any<CancellationToken>());
response.Messages[0].Text.Should()
.BeEquivalentTo(testCase.ResponseModel.Output.Choices[0].Message.Content[0].Text);
Assert.Equal(testCase.ResponseModel.Output.Choices[0].Message.Content[0].Text, response.Messages[0].Text);
}

[Fact]
Expand Down Expand Up @@ -191,6 +190,6 @@ public async Task ChatClient_ImageRecognitionStream_SuccessAsync()
_ = dashScopeClient.Received().GetMultimodalGenerationStreamAsync(
Arg.Is<ModelRequest<MultimodalInput, IMultimodalParameters>>(m => m.IsEquivalent(testCase.RequestModel)),
Arg.Any<CancellationToken>());
text.ToString().Should().Be(testCase.ResponseModel.Output.Choices.First().Message.Content[0].Text);
Assert.Equal(testCase.ResponseModel.Output.Choices.First().Message.Content[0].Text, text.ToString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
10 changes: 5 additions & 5 deletions test/Cnblogs.DashScope.AI.UnitTests/EmbeddingClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Cnblogs.DashScope.Core;
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;
using Microsoft.Extensions.AI;
using NSubstitute;
using NSubstitute.Extensions;
Expand Down Expand Up @@ -34,10 +33,11 @@ public async Task EmbeddingClient_Text_SuccessAsync()

// Assert
_ = dashScopeClient.Received().GetEmbeddingsAsync(
Arg.Is<ModelRequest<TextEmbeddingInput, ITextEmbeddingParameters>>(
m => m.IsEquivalent(testCase.RequestModel)),
Arg.Is<ModelRequest<TextEmbeddingInput, ITextEmbeddingParameters>>(m
=> m.IsEquivalent(testCase.RequestModel)),
Arg.Any<CancellationToken>());
response.Select(x => x.Vector.ToArray()).Should()
.BeEquivalentTo(testCase.ResponseModel.Output.Embeddings.Select(x => x.Embedding));
Assert.Equivalent(
testCase.ResponseModel.Output.Embeddings.Select(x => x.Embedding),
response.Select(x => x.Vector.ToArray()));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;
using NSubstitute;

namespace Cnblogs.DashScope.Sdk.UnitTests;
Expand All @@ -21,7 +20,7 @@ public async Task SingleCompletion_TextNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}

[Fact]
Expand All @@ -39,7 +38,7 @@ public async Task SingleCompletion_ThoughtNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}

[Fact]
Expand All @@ -58,11 +57,17 @@ public async Task SingleCompletion_TextSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
outputs.SkipLast(1).Should().AllSatisfy(x => x.Output.FinishReason.Should().Be("null"));
outputs.Last().Should().BeEquivalentTo(
testCase.ResponseModel,
o => o.Excluding(y => y.Output.Text).Excluding(x => x.Output.Thoughts));
text.Should().Be(testCase.ResponseModel.Output.Text);
Assert.All(outputs.SkipLast(1), x => Assert.Equal("null", x.Output.FinishReason));
Assert.Equal(testCase.ResponseModel.Output.Text, text);
var last = outputs.Last();
last = last with
{
Output = last.Output with
{
Text = testCase.ResponseModel.Output.Text, Thoughts = testCase.ResponseModel.Output.Thoughts
}
};
Assert.Equivalent(testCase.ResponseModel, last);
}

[Fact]
Expand All @@ -80,7 +85,7 @@ public async Task ConversationCompletion_SessionIdNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}

[Fact]
Expand All @@ -98,7 +103,7 @@ public async Task ConversationCompletion_MessageNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}

[Fact]
Expand All @@ -116,7 +121,7 @@ public async Task SingleCompletion_MemoryNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}

[Fact]
Expand All @@ -134,6 +139,6 @@ public async Task SingleCompletion_WorkflowNoSse_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;

using NSubstitute;

namespace Cnblogs.DashScope.Sdk.UnitTests;
Expand All @@ -21,6 +21,6 @@ public async Task BackgroundGeneration_CreateTask_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
response.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0"/>
<PackageReference Include="NSubstitute" Version="5.3.0"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
26 changes: 15 additions & 11 deletions test/Cnblogs.DashScope.Sdk.UnitTests/DashScopeClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
using System.Net.Http.Headers;
using System.Reflection;
using Cnblogs.DashScope.Core;
using FluentAssertions;
using Xunit.Abstractions;

namespace Cnblogs.DashScope.Sdk.UnitTests;

public class DashScopeClientTests
{
private readonly ITestOutputHelper _output;

public DashScopeClientTests(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public void DashScopeClient_Constructor_New()
{
// Arrange
const string apiKey = "apiKey";

// Act
var act = () => new DashScopeClient(apiKey);

// Assert
act.Should().NotThrow();
var client = new DashScopeClient(apiKey);
_output.WriteLine("hash: " + client.GetHashCode()); // do something to avoid optimization
}

[Theory]
Expand All @@ -37,7 +42,7 @@ public void DashScopeClient_Constructor_NotCacheableParams(
var value2 = HttpClientAccessor.GetValue(client2);

// Assert
value.Should().NotBe(value2);
Assert.NotSame(value2, value);
}

[Theory]
Expand All @@ -57,7 +62,7 @@ public void DashScopeClient_Constructor_CacheableParams(
var value2 = HttpClientAccessor.GetValue(client2);

// Assert
value.Should().Be(value2);
Assert.Same(value2, value);
}

[Fact]
Expand All @@ -71,8 +76,7 @@ public void DashScopeClient_Constructor_WithApiKeyHeader()
var value = HttpClientAccessor.GetValue(client) as HttpClient;

// Assert
value?.DefaultRequestHeaders.Authorization?.Should()
.BeEquivalentTo(new AuthenticationHeaderValue("Bearer", apiKey));
Assert.Equivalent(new AuthenticationHeaderValue("Bearer", apiKey), value?.DefaultRequestHeaders.Authorization);
}

[Fact]
Expand All @@ -87,7 +91,7 @@ public void DashScopeClient_Constructor_WithWorkspaceId()
var value = HttpClientAccessor.GetValue(client) as HttpClient;

// Assert
value?.DefaultRequestHeaders.GetValues("X-DashScope-WorkSpace").Should().BeEquivalentTo(workspaceId);
Assert.Equal(workspaceId, value?.DefaultRequestHeaders.GetValues("X-DashScope-WorkSpace").First());
}

[Fact]
Expand All @@ -102,7 +106,7 @@ public void DashScopeClient_Constructor_WithPrivateEndpoint()
var value = HttpClientAccessor.GetValue(client) as HttpClient;

// Assert
value?.BaseAddress.Should().BeEquivalentTo(new Uri(privateEndpoint));
Assert.Equivalent(new Uri(privateEndpoint), value?.BaseAddress);
}

public static TheoryData<string, string, TimeSpan?, TimeSpan?> ParamsShouldNotCache
Expand Down
19 changes: 12 additions & 7 deletions test/Cnblogs.DashScope.Sdk.UnitTests/ErrorTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Cnblogs.DashScope.Core;
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using NSubstitute.Extensions;
Expand All @@ -21,7 +20,8 @@ public async Task Error_AuthError_ExceptionAsync()
var act = async () => await client.GetTextCompletionAsync(testCase.RequestModel);

// Assert
(await act.Should().ThrowAsync<DashScopeException>()).And.Error.Should().BeEquivalentTo(testCase.ResponseModel);
var ex = await Assert.ThrowsAsync<DashScopeException>(act);
Assert.Equivalent(testCase.ResponseModel, ex.Error);
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
Expand All @@ -39,7 +39,8 @@ public async Task Error_ParameterErrorNoSse_ExceptionAsync()
var act = async () => await client.GetTextCompletionAsync(testCase.RequestModel);

// Assert
(await act.Should().ThrowAsync<DashScopeException>()).And.Error.Should().BeEquivalentTo(testCase.ResponseModel);
var ex = await Assert.ThrowsAsync<DashScopeException>(act);
Assert.Equivalent(testCase.ResponseModel, ex.Error);
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
Expand All @@ -58,7 +59,8 @@ public async Task Error_ParameterErrorSse_ExceptionAsync()
var act = async () => await stream.LastAsync();

// Assert
(await act.Should().ThrowAsync<DashScopeException>()).And.Error.Should().BeEquivalentTo(testCase.ResponseModel);
var ex = await Assert.ThrowsAsync<DashScopeException>(act);
Assert.Equivalent(testCase.ResponseModel, ex.Error);
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(m => Checkers.IsJsonEquivalent(m.Content!, testCase.GetRequestJson(sse))),
Arg.Any<CancellationToken>());
Expand All @@ -71,13 +73,15 @@ public async Task Error_NetworkError_ExceptionAsync()
var (client, handler) = Sut.GetTestClient();
handler.Configure().MockSend(Arg.Any<HttpRequestMessage>(), Arg.Any<CancellationToken>())
.Throws(new InvalidOperationException("Network error!"));
var testCase = Snapshots.TextGeneration.TextFormat.SinglePrompt;

// Act
var act = async ()
=> await client.GetTextCompletionAsync(Snapshots.TextGeneration.TextFormat.SinglePrompt.RequestModel);
=> await client.GetTextCompletionAsync(testCase.RequestModel);

// Assert
(await act.Should().ThrowAsync<DashScopeException>()).And.Error.Should().BeNull();
var ex = await Assert.ThrowsAsync<DashScopeException>(act);
Assert.Null(ex.Error);
}

[Fact]
Expand All @@ -94,6 +98,7 @@ public async Task Error_OpenAiCompatibleError_ExceptionAsync()
"other");

// Assert
(await act.Should().ThrowAsync<DashScopeException>()).And.Error.Should().BeEquivalentTo(testCase.ResponseModel);
var ex = await Assert.ThrowsAsync<DashScopeException>(act);
Assert.Equivalent(testCase.ResponseModel, ex.Error);
}
}
10 changes: 5 additions & 5 deletions test/Cnblogs.DashScope.Sdk.UnitTests/FileSerializationTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Cnblogs.DashScope.Tests.Shared.Utils;
using FluentAssertions;

using NSubstitute;

namespace Cnblogs.DashScope.Sdk.UnitTests;
Expand All @@ -21,7 +21,7 @@ public async Task File_Upload_SuccessAsync()
handler.Received().MockSend(
Arg.Is<HttpRequestMessage>(r => r.RequestUri!.AbsolutePath == "/compatible-mode/v1/files"),
Arg.Any<CancellationToken>());
task.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, task);
}

[Fact]
Expand All @@ -40,7 +40,7 @@ public async Task File_Get_SuccessAsync()
Arg.Is<HttpRequestMessage>(
r => r.RequestUri!.AbsolutePath == "/compatible-mode/v1/files/" + testCase.ResponseModel.Id.Value),
Arg.Any<CancellationToken>());
task.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, task);
}

[Fact]
Expand All @@ -55,7 +55,7 @@ public async Task File_List_SuccessAsync()
var list = await client.ListFilesAsync();

// Assert
list.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, list);
}

[Fact]
Expand All @@ -74,6 +74,6 @@ public async Task File_Delete_SuccessAsync()
Arg.Is<HttpRequestMessage>(
r => r.RequestUri!.AbsolutePath == "/compatible-mode/v1/files/" + testCase.ResponseModel.Id.Value),
Arg.Any<CancellationToken>());
task.Should().BeEquivalentTo(testCase.ResponseModel);
Assert.Equivalent(testCase.ResponseModel, task);
}
}
Loading