使用内存数据模拟Microsoft Graph API单元测试空列表问题排查
单元测试返回空列表问题排查
问题背景
尝试通过模拟依赖创建用户列表,对仓储类的用户列表返回方法做单元测试,验证仓储方法是否返回预期的用户列表,但测试始终返回空列表,怀疑测试传参存在遗漏。
核心代码
GraphAPI类的GetUsersAsync方法
public Task<IGraphServiceUsersCollectionPage> GetUsersAsync() { return this.appClient.Users .Request(this.queryOptions) .Select(@$" Id, DisplayName, GivenName, Surname, Mail, OtherMails, CompanyName,") .OrderBy("DisplayName") .GetAsync(); }
B2CRepository仓储类
public class B2CRepository : IB2CRepository { private readonly IGraphAPI graphApi; public B2CRepository(IGraphAPI graphApi) { this.graphApi = graphApi; } private List<User> GetUsersOnly() { var request = this.graphApi.GetUsersAsync().Result; List<User> users = new List<User>(); var graphUsers = request.ToList(); do { users.AddRange(graphUsers); var nextPage = request.NextPageRequest; graphUsers = nextPage?.GetAsync().Result.ToList() ?? new List<User>(); } while (graphUsers.Count > 0); return users; } }
现有测试代码
测试中模拟了GraphAPI类:
var mockGraphAPI = new Mock<IGraphAPI>();
测试方法如下,目标是传入用户列表,让仓储方法GetUsersOnly()返回该列表:
[TestMethod] public void GetUserTest() { var users = new List<User>(); var mockGraphAPI = new Mock<IGraphAPI>(); for (int i = 0; i < 3; i++) { var user = new User() { DisplayName = "TestUser2" + i, }; users.Add(user); } var mockUserPageResult = new Mock<IGraphServiceUsersCollectionPage>(); mockGraphAPI.Setup(api => api.GetUsersAsync()).ReturnsAsync(mockUserPageResult.Object); mockUserPageResult.SetupGet(page => page.NextPageRequest); this.b2CRepository = new B2CRepository(mockGraphAPI.Object); var usersResult = this.b2CRepository.GetUsers(); Assert.IsTrue(usersResult.Count() == 2); }
问题原因与修复方案
问题点
- 模拟的
IGraphServiceUsersCollectionPage未配置返回预设的用户列表,调用ToList()时会返回空集合 - 断言中验证的数量(2)与创建的用户数量(3)不匹配
NextPageRequest未明确设置为null,可能导致循环中出现不必要的空引用风险
修复后的测试代码
[TestMethod] public void GetUserTest() { // 创建测试用户列表 var testUsers = new List<User>(); for (int i = 0; i < 3; i++) { testUsers.Add(new User() { DisplayName = "TestUser2" + i, }); } // 模拟用户分页结果,配置枚举行为返回测试用户 var mockUserPage = new Mock<IGraphServiceUsersCollectionPage>(); mockUserPage.As<IEnumerable<User>>().Setup(x => x.GetEnumerator()) .Returns(testUsers.GetEnumerator()); // 配置NextPageRequest为null,无需分页 mockUserPage.SetupGet(page => page.NextPageRequest).Returns(null); // 模拟GraphAPI,返回上述分页结果 var mockGraphAPI = new Mock<IGraphAPI>(); mockGraphAPI.Setup(api => api.GetUsersAsync()) .ReturnsAsync(mockUserPage.Object); // 实例化仓储并调用方法 var b2CRepository = new B2CRepository(mockGraphAPI.Object); var resultUsers = b2CRepository.GetUsers(); // 断言结果数量与测试用户数量一致 Assert.AreEqual(testUsers.Count, resultUsers.Count()); }
关键修复说明
- 给
mockUserPage添加IEnumerable<User>的模拟,确保ToList()能获取到预设的测试用户 - 将
NextPageRequest明确设为null,避免循环中尝试获取下一页 - 修正断言逻辑,使用
Assert.AreEqual替代IsTrue,让断言更清晰准确
内容的提问来源于stack exchange,提问作者Tim Whatley
相关产品推荐
相关产品推荐

