Mock TableClient.QueryAsync<TableEntity>返回空列表,单元测试排查
解决TableClient.QueryAsync Mock返回空列表的问题
核心问题排查
你的测试返回空列表,核心遗漏点有两个:
1. Mock的TableClient未关联到依赖注入的Factory
被测类SettingsRepo依赖ITableFactoryService,但测试中没有配置Factory返回你Mock的fakeTableClient。这导致SettingsRepo实际使用的TableClient并非你预设返回值的Mock实例,自然不会返回预期数据。
2. QueryAsync的参数匹配可能不精准
你使用了精确的查询字符串匹配A<string>.That.Matches(s => s == "PartitionKey eq 'default'"),如果被测方法中实际传入的查询字符串有细微差异(比如空格、引号格式),Mock会不生效,返回默认的空AsyncPageable。
修正步骤
步骤1:关联Factory与Mock的TableClient
添加Factory的Mock配置,确保SettingsRepo能获取到你预设的fakeTableClient:
// 按实际接口方法名调整,示例为GetTableClient A.CallTo(() => fakeTableServiceClient.GetTableClient(A<string>._)) .Returns(fakeTableClient);
步骤2:放宽参数匹配(先验证核心逻辑)
暂时替换精确匹配为通配符,排除参数不匹配的干扰:
A.CallTo(() => fakeTableClient.QueryAsync<TableEntity>( A<string>._, A<int>._, A<IEnumerable<string>>._, A<CancellationToken>._)) .Returns(tables);
测试通过后,再逐步缩小匹配范围到实际的查询字符串。
步骤3:验证被测方法的遍历逻辑
确保被测方法正确遍历AsyncPageable<TableEntity>:
// 被测方法参考示例 public async Task<List<string>> GetAllSettingsAsync() { var tableClient = _tableFactoryService.GetTableClient("your-table-name"); var entities = tableClient.QueryAsync<TableEntity>("PartitionKey eq 'default'"); var result = new List<string>(); await foreach (var entity in entities) { // 按业务逻辑转换为字符串,示例取RowKey result.Add(entity.RowKey); } return result; }
若未使用await foreach遍历,也会导致返回空列表。
调整后的完整测试代码
[Fact] public async Task GetAllSettingsAsync_ShouldReturnListOfStrings() { // Arrange var fakeConfiguration = A.Fake<IConfiguration>(); var fakeTableServiceClient = A.Fake<ITableFactoryService>(); var fakeTableClient = A.Fake<TableClient>(); // 关联Factory到Mock的TableClient A.CallTo(() => fakeTableServiceClient.GetTableClient(A<string>._)) .Returns(fakeTableClient); Page<TableEntity> page = Page<TableEntity>.FromValues( new List<TableEntity> { new TableEntity("p1", "k1"), new TableEntity("p2", "k2"), new TableEntity("p3", "k3"), }, continuationToken: null, A.Fake<Response>()); AsyncPageable<TableEntity> tables = AsyncPageable<TableEntity>.FromPages(new[] { page }); // 放宽参数匹配确保Mock生效 A.CallTo(() => fakeTableClient.QueryAsync<TableEntity>( A<string>._, A<int>._, A<IEnumerable<string>>._, A<CancellationToken>._)).Returns(tables); var cut = new SettingsRepo(fakeConfiguration, fakeTableServiceClient); // Act var result = await cut.GetAllSettingsAsync(); // Assert Assert.Equal(3, result.Count); Assert.Contains("k1", result); }
内容的提问来源于stack exchange,提问作者thinker
相关产品推荐
相关产品推荐

