在带有 out 参数的 NSubstitute 模拟方法中返回不同的值 [英] returning different values in an NSubstitute mock method with an out parameter

查看:25
本文介绍了在带有 out 参数的 NSubstitute 模拟方法中返回不同的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一种用来模拟的方法...

Given a method with which to mock...

public bool TryReceive(out T message, TimeSpan millisecondsToWait)

  • 我希望在前两次调用中设置不同的消息,然后返回真的.
  • 后续调用返回 false.
  • 我尝试了一些变体,在任何一种情况下,lambda 表达式都会执行一次,并且不再执行.NSubstitute 似乎缓存第一个返回值,并一遍又一遍地使用相同的值.

    I have tried a few variations, and in either case, the lambda expression is executed once, and never again. NSubstitute seems to be caching the first return value, and using the same value over and over.

    我已经试过了...

    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;
                });
    

    我能想到的唯一选择是为测试目的提供缓冲区的完整替代实现.我的感觉是,鉴于此文档,应该是可能的.

    The only option I can think of is to provide a complete substitute implementation of the buffer for test purposes. My feeling is that given this documentation, it should be possible.

    编辑

    我一直无法使用 NSubstitute 使其工作,但是如果我使用

    I have been unable to get this working using NSubstitute, however if I provide a mock implementation of the IMessageBuffer<TCR> using

    // mock buffer will return the necessary values by maintaining
    // the relevant state internally.
    container.Provide<IMessageBuffer<TCR>>(new MockBuffer());
    

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

    it works correctly, so it's not a lifetimescope issue. Somehow NSubstitute seems to be calling the mocked out method only the first time, and reusing the value (or operating in such a way that it seems to reuse the value) - very strange.

    推荐答案

    NSubstitute 在 outref 参数方面有点挣扎.

    NSubstitute struggles a bit with out and ref parameters.

    问题在于当我们存根时:

    The problem is that when we stub:

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

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

    this will only execute when @out is the original value. This value will change the first time it is called, so the Returns lambda won't execute again (NSub thinks it is a different, non-matching call).

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

    The easiest way to work-around this is to switch to ReturnsForAnyArgs(...):

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

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

    This will work for all TryReceive calls, regardless of the parameter values, so the lambda should always execute. The downside of this is that if you want this to only run for specific values of the second argument then you'll have to put that logic inside the lambda (rather than using an argument matcher).

    这篇关于在带有 out 参数的 NSubstitute 模拟方法中返回不同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆