You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对使用NuGet包的类库方法开展测试?

MyService类方法的测试方案

一、测试类型选择

  • 优先单元测试:这两个方法的核心是与外部依赖(MyClient、配置、MyAccountsRepository)的交互,单元测试可通过Mock隔离这些外部组件,快速验证自身逻辑的正确性,执行效率高,能覆盖大部分场景。
  • 辅助集成测试:如果需要验证端到端流程(比如和真实授权服务、数据库交互),可补充少量集成测试,但不用覆盖所有场景,单元测试才是主力。

二、各方法的测试内容与用例

1. AuthorizationLogin方法

测试覆盖点:

  • 确认方法确实调用了MyClient的BuildUri方法,且直接返回该方法的结果,无额外篡改逻辑。

单元测试示例(基于xUnit + Moq框架):

using Moq;
using Xunit;

public class MyServiceTests
{
    private readonly Mock<IMyClient> _mockMyClient;
    private readonly MyService _myService;

    public MyServiceTests()
    {
        _mockMyClient = new Mock<IMyClient>();
        // 假设MyService通过构造函数注入依赖
        _myService = new MyService(
            _mockMyClient.Object, 
            Mock.Of<IConfiguration>(), 
            Mock.Of<IMyAccountsRepository>()
        );
    }

    [Fact]
    public void AuthorizationLogin_ReturnsExactUriFromMyClient()
    {
        // 准备测试数据
        var expectedAuthUri = "https://auth.example.com/authorize?client_id=test&scope=read";
        _mockMyClient.Setup(client => client.BuildUri()).Returns(expectedAuthUri);

        // 执行方法
        var resultUri = _myService.AuthorizationLogin();

        // 验证结果
        Assert.Equal(expectedAuthUri, resultUri);
        // 确保BuildUri仅被调用一次
        _mockMyClient.Verify(client => client.BuildUri(), Times.Once);
    }
}

2. ExchangeCodeForToken方法

测试覆盖点:

  • 确认方法正确传入code参数调用MyClient的RequestTokenAsync
  • 确认方法从配置中正确读取MyClient:Scopes的值
  • 确认方法用返回的令牌和配置的Scope构造MyAccounts对象,并调用Repository的AddAccount方法
  • 异常场景:当MyClient请求令牌抛出异常时,方法是否正确传递异常(无特殊捕获逻辑的情况下)

单元测试示例:

[Fact]
public async Task ExchangeCodeForToken_ValidCode_AddsCorrectAccountToRepository()
{
    // 准备测试数据
    var testCode = "auth-code-abc123";
    var mockToken = new TokenResponse
    {
        AccessToken = "test-access-token",
        RefreshToken = "test-refresh-token"
    };
    var testScopes = "read write profile";

    // Mock配置
    var mockConfig = new Mock<IConfiguration>();
    mockConfig.Setup(config => config["MyClient:Scopes"]).Returns(testScopes);

    // MockMyClient的请求令牌方法
    _mockMyClient.Setup(client => client.RequestTokenAsync(testCode))
                 .ReturnsAsync(mockToken);

    // Mock账户仓库
    var mockAccountRepo = new Mock<IMyAccountsRepository>();
    var myService = new MyService(
        _mockMyClient.Object, 
        mockConfig.Object, 
        mockAccountRepo.Object
    );

    // 执行方法
    await myService.ExchangeCodeForToken(testCode);

    // 验证调用
    _mockMyClient.Verify(client => client.RequestTokenAsync(testCode), Times.Once);
    // 验证账户对象属性正确且被添加到仓库
    mockAccountRepo.Verify(repo => repo.AddAccount(It.Is<MyAccounts>(account =>
        account.AccessToken == mockToken.AccessToken &&
        account.RefreshToken == mockToken.RefreshToken &&
        account.Scopes == testScopes
    )), Times.Once);
}

[Fact]
public async Task ExchangeCodeForToken_TokenRequestFails_PropagatesException()
{
    // 准备测试数据
    var testCode = "invalid-code";
    var requestException = new HttpRequestException("Failed to fetch token: invalid grant");
    _mockMyClient.Setup(client => client.RequestTokenAsync(testCode))
                 .ThrowsAsync(requestException);

    var myService = new MyService(
        _mockMyClient.Object, 
        Mock.Of<IConfiguration>(), 
        Mock.Of<IMyAccountsRepository>()
    );

    // 验证异常被正确抛出
    var thrownException = await Assert.ThrowsAsync<HttpRequestException>(
        () => myService.ExchangeCodeForToken(testCode)
    );
    Assert.Equal(requestException.Message, thrownException.Message);
}

三、集成测试补充(可选)

如果要做集成测试,需要:

  • 使用真实的MyClient实例,配置测试环境的OAuth参数(比如测试用client_id、授权地址)
  • 使用内存数据库或测试专用数据库作为MyAccountsRepository的实现
  • 测试流程:调用AuthorizationLogin拿到授权地址,模拟授权获取code,再调用ExchangeCodeForToken,最后验证数据库中是否正确存储了账户信息

内容的提问来源于stack exchange,提问作者Liam Kenny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:28:16