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

Cosmos SDK v3+中如何为FeedResponse注入模拟值(NSubstitute+NUnit)

解决NSubstitute Mock CosmosDB FeedResponse无法注入测试数据的问题

你遇到的核心问题是:FeedResponse是抽象类,它接收IEnumerable的构造函数是protected的,而NSubstitute只能通过公共构造函数创建Mock实例,所以直接用Substitute.For<FeedResponse<T>>(mockApplicationList)会报错找不到构造函数。

下面给你两种实用的解决方案,根据你的测试需求选择:

方案一:自定义FeedResponse子类(灵活可控)

如果需要模拟FeedResponse的其他属性(比如请求耗时、状态码等),或者希望更贴近真实的FeedResponse行为,建议自己实现一个子类:

public class TestFeedResponse<T> : FeedResponse<T>
{
    private readonly IEnumerable<T> _items;

    public TestFeedResponse(IEnumerable<T> items)
    {
        _items = items;
    }

    // 重写枚举器方法,返回测试数据
    public override IEnumerator<T> GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    // 可选:如果需要测试其他属性,比如RequestCharge,可以重写对应的属性
    public override double RequestCharge => 1.0;
    public override HttpStatusCode StatusCode => HttpStatusCode.OK;
}

然后在你的测试代码中直接实例化这个子类,代替Mock:

// 准备测试数据
var mockApplicationList = new List<YourEntityType> 
{ 
    new YourEntityType { /* 属性赋值 */ },
    new YourEntityType { /* 属性赋值 */ }
};

// 创建自定义的FeedResponse实例
var testFeedResponse = new TestFeedResponse<YourEntityType>(mockApplicationList);

// 配置FeedIterator的行为
this.mockFeedIterator.ReadNextAsync().Returns(Task.FromResult(testFeedResponse));
// 注意:要控制HasMoreResults避免无限循环,比如第一次返回true,第二次返回false
this.mockFeedIterator.HasMoreResults.Returns(true, false);

方案二:直接Mock FeedResponse的枚举行为(快速简洁)

如果只需要模拟返回的列表项,不需要关心FeedResponse的其他属性,可以直接Mock它的GetEnumerator方法:

// 准备测试数据
var mockApplicationList = new List<YourEntityType> 
{ 
    new YourEntityType { /* 属性赋值 */ },
    new YourEntityType { /* 属性赋值 */ }
};

// Mock FeedResponse
var mockFeedResponse = Substitute.For<FeedResponse<YourEntityType>>();
// 让它返回测试数据的枚举器
mockFeedResponse.GetEnumerator().Returns(mockApplicationList.GetEnumerator());

// 配置FeedIterator
this.mockFeedIterator.ReadNextAsync().Returns(Task.FromResult(mockFeedResponse));
// 同样要控制HasMoreResults的返回值
this.mockFeedIterator.HasMoreResults.Returns(true, false);

额外提醒

你的测试代码里的while (feedIterator.HasMoreResults)循环,如果HasMoreResults一直返回true会导致无限循环,所以一定要用Returns(true, false)这种方式,让迭代器在一次读取后就停止返回更多结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:03:11