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

如何在仓储模式下Mock带筛选参数的Microsoft Graph API并做单元测试

仓储模式下Mock Microsoft Graph API的单元测试方案

你的问题核心是当前Mock设置忽略了传入的筛选参数,导致无论传什么值都返回全部用户,无法验证仓储层的筛选调用逻辑。以下是正确的Mock和单元测试实现方式:

1. 准备测试数据

先定义一组测试用的用户数据,覆盖不同筛选场景:

// 假设TMUser是你的业务用户模型,User是Graph API的用户模型
private readonly List<TMUser> _testUsers = new List<TMUser>
{
    new TMUser { Id = "1", DisplayName = "TestUser-1", GivenName = "John", Mail = "john@test.com" },
    new TMUser { Id = "2", DisplayName = "AnotherUser", GivenName = "Jane", Mail = "jane@test.com" },
    new TMUser { Id = "3", DisplayName = "TestUser-2", GivenName = "Test", Mail = "test@test.com" }
};

2. 正确配置Mock逻辑

不要用It.IsAny<string>()固定返回全部数据,而是通过回调函数根据传入的参数动态模拟Graph API的筛选行为:

private readonly Mock<IGraphAPI> _graphApiMock = new Mock<IGraphAPI>();

// 在测试初始化方法([TestInitialize])中配置Mock
[TestInitialize]
public void Setup()
{
    // 将业务用户模型转换为Graph API的User模型集合
    var graphUsers = _testUsers.Select(u => new User
    {
        Id = u.Id,
        DisplayName = u.DisplayName,
        GivenName = u.GivenName,
        Surname = u.Surname,
        Mail = u.Mail,
        OtherMails = u.OtherMails,
        CompanyName = u.CompanyName
    }).ToList();

    // 配置Mock:根据传入的param参数筛选并返回结果
    _graphApiMock.Setup(api => api.GetUserByNameAsync(It.IsAny<string>()))
        .ReturnsAsync((string param) =>
        {
            // 模拟Graph API的筛选逻辑(和真实API逻辑一致)
            var filteredUsers = graphUsers.Where(u =>
                u.DisplayName.StartsWith(param, StringComparison.OrdinalIgnoreCase) ||
                u.GivenName.StartsWith(param, StringComparison.OrdinalIgnoreCase) ||
                u.Surname.StartsWith(param, StringComparison.OrdinalIgnoreCase) ||
                u.Mail.StartsWith(param, StringComparison.OrdinalIgnoreCase)
            ).ToList();

            // 包装成Graph API返回的集合页类型
            return new GraphServiceUsersCollectionPage(filteredUsers, null);
        });

    // 初始化仓储实例,注入Mock的IGraphAPI
    this.b2CRepository = new B2CRepository(_graphApiMock.Object);
}

3. 编写单元测试用例

测试用例需要验证三个核心点:返回结果符合预期、参数正确传递给Graph API、方法调用次数正确:

[TestMethod]
public async Task GetUsersByName_WithValidParam_ReturnsFilteredUsers()
{
    // Arrange
    var searchParam = "TestUser-";
    var expectedUserCount = 2;

    // Act
    var result = await this.b2CRepository.GetUsersByName(searchParam); // 建议把仓储方法改成异步,避免.Result死锁

    // Assert
    // 验证返回数量正确
    Assert.AreEqual(expectedUserCount, result.Count);
    // 验证所有返回用户都匹配筛选条件
    Assert.IsTrue(result.All(u => u.DisplayName.StartsWith(searchParam)));
    // 验证Graph API方法被调用一次,且参数正确
    _graphApiMock.Verify(api => api.GetUserByNameAsync(searchParam), Times.Once);
}

[TestMethod]
public async Task GetUsersByName_WithNoMatchingParam_ReturnsEmptyList()
{
    // Arrange
    var searchParam = "NonExistentUser";

    // Act
    var result = await this.b2CRepository.GetUsersByName(searchParam);

    // Assert
    Assert.AreEqual(0, result.Count);
    _graphApiMock.Verify(api => api.GetUserByNameAsync(searchParam), Times.Once);
}

关键注意事项

  • 仓储层的GetUsersByName方法建议改为异步(返回Task<List<TMUser>>),避免使用.Result导致的死锁风险。
  • 单元测试只关注仓储层的逻辑:是否正确传递参数、是否正确转换Graph API的返回结果,不要测试Graph API本身的筛选逻辑(那是集成测试的范畴)。
  • 使用Verify方法验证依赖的IGraphAPI接口是否被正确调用,确保仓储层的逻辑符合预期。

内容的提问来源于stack exchange,提问作者Tim Whatley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:40:23