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

如何用Moq实现首次调用返回指定值,后续所有调用返回另一组值?

用Moq实现首次调用方法返回一组值,后续调用均返回另一组值

我需要用Moq实现这样的逻辑:首次调用GetMessages()方法时返回指定的消息集合,后续所有调用都返回空集合。我尝试了以下几种方案,但都无法可靠运行,其中方案5的SetupSequence仅在调用次数完全匹配时有效,但我的调用次数可能超过100次,所以没法用这个方法。

方案1

var invocations = 0;
_mockSqsMessageManager.Setup(x => x.GetMessages())
    .ReturnsAsync(() => invocations > 0 ? new List<SqsMessage>() : messages)
    .Callback(() =>
    {
        invocations++;
    });

方案2

_mockSqsMessageManager.Setup(x => x.GetMessages())
    .ReturnsAsync(messages)
    .Callback(() =>
    {
        _mockSqsMessageManager.Setup(x => x.GetMessages())
            .ReturnsAsync(new List<SqsMessage>());
    });

方案3

var invocations = 0;
_mockSqsMessageManager.Setup(x => x.GetMessages())
    .ReturnsAsync(messages)
    .Callback(() =>
    {
        invocations++;
        if (invocations > 0)
        {
            messages = new List<SqsMessage>();
        }
    });

方案4

_mockSqsMessageManager.Setup(x => x.GetMessages())
    .ReturnsAsync(() =>
    {
        var invocations = _mockSqsMessageManager.Invocations.Count(x => x.MatchingSetup.Expression.Body.ToString() == "x.GetMessages()");
        return invocations > 0 ? new List<SqsMessage>() : messages;
    });

方案5

_mockSqsMessageManager.SetupSequence(x => x.GetMessages())
    .ReturnsAsync(messages)
    .ReturnsAsync(new List<SqsMessage>());

正确实现方式

用闭包变量跟踪首次调用状态是最简洁可靠的方案,逻辑清晰且不受调用次数限制:

var isFirstCall = true;
_mockSqsMessageManager.Setup(x => x.GetMessages())
    .ReturnsAsync(() => 
    {
        if (isFirstCall)
        {
            isFirstCall = false;
            return messages;
        }
        return new List<SqsMessage>();
    });

首次调用时返回目标集合,同时将isFirstCall置为false,之后所有调用都会返回空集合,无论后续调用多少次都能稳定工作。

内容的提问来源于stack exchange,提问作者Vergil C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:15:37