在带有out参数的NSubstitute模拟方法中返回不同的值

本文关键字:返回 方法 NSubstitute out 参数 模拟 | 更新日期: 2023-09-27 17:52:15

给出一个方法来模拟…

public bool TryReceive(out T message, TimeSpan millisecondsToWait)
  • 我希望在前两次呼叫中设置不同的消息,并返回真实的。
  • 后续调用返回false。

我尝试了一些变化,在任何一种情况下,lambda表达式执行一次,再也不会执行了。NSubstitute似乎是缓存第一个返回值,并反复使用相同的值。

I have try this…

TCR @out;
var container = new AutoSubstitute();
var mb = container.Resolve<IMessageBuffer<TCR>>();
mb.TryReceive(out @out, Arg.Any<TimeSpan>()).Returns(
            _ => { _[0] = buy; return true; },
            _ => { _[0] = sell; return true; },
            _ => { _[0] = null; return false; });

和我已经试过了:

        bool? bs = true;
        TCR @out;
        var container = new AutoSubstitute();
        var mb = container.Resolve<IMessageBuffer<TCR>>();
        mb.TryReceive(out @out, Arg.Any<TimeSpan>()).Returns(
            _ =>
            {
                if (bs == true)
                {
                    _[0] = buy;
                    bs = false;
                    return true;
                }
                if (bs == false)
                {
                    _[0] = sell;
                    bs = null;
                    return true;
                }
                _[0] = null;
                return false;
            });

我能想到的唯一选择是为测试目的提供一个完整的缓冲区替代实现。我的感觉是,有了这份文档,这应该是可能的。

编辑

我一直无法使用NSubstitute获得此工作,但是,如果我使用

提供IMessageBuffer<TCR>的模拟实现
// mock buffer will return the necessary values by maintaining
// the relevant state internally.
container.Provide<IMessageBuffer<TCR>>(new MockBuffer());

可以正常工作,所以这不是生命周期的问题。不知怎的,NSubstitute似乎只在第一次调用模拟出方法,并重用该值(或以似乎重用该值的方式操作)-非常奇怪。

在带有out参数的NSubstitute模拟方法中返回不同的值

NSubstitute在outref参数上有点挣扎。

问题是当我们存根:

mb.TryReceive(out @out, Arg.Any<TimeSpan>()).Returns(...)

仅在@out为原始值时执行。这个值会在第一次被调用时改变,所以Returns lambda不会再次执行(NSub认为它是一个不同的,不匹配的调用)。

最简单的解决方法是切换到ReturnsForAnyArgs(...):

mb.TryReceive(out @out, Arg.Any<TimeSpan>()).ReturnsForAnyArgs(action0, action1, action2);

这将适用于所有TryReceive调用,无论参数值如何,因此lambda应该始终执行。这样做的缺点是,如果您希望只对第二个参数的特定值运行,那么您必须将该逻辑放入lambda中(而不是使用参数匹配器)。