NSubstitute完全手册(十二)使用回调函数和WhenDo语法

有时当收到一个特殊的调用时能执行一些代码是非常有用的。我们在使用函数设置返回值一节已经看到了类似的代码。

复制代码
    public interface ICalculator
    {
      int Add(int a, int b);
      string Mode { get; set; }
    }

    [TestMethod]
    public void Test_CallbacksWhenDo_PassFunctionsToReturns()
    {
      var calculator = Substitute.For<ICalculator>();

      var counter = 0;
      calculator
        .Add(0, 0)
        .ReturnsForAnyArgs(x => 0)
        .AndDoes(x => counter++);

      calculator.Add(7, 3);
      calculator.Add(2, 2);
      calculator.Add(11, -3);
      Assert.AreEqual(counter, 3);
    }
复制代码

关于传递函数参数,在使用函数设置返回值这一节有更详细的介绍。

为无返回值调用创建回调

Returns() 可以被用于为成员设置产生返回值的回调函数,但是对于 void 类型的成员,我们需要不同的方式,因为我们无法调用一个 void 并返回一个值。对于这种情况,我们可以使用 When..Do 语法。

当被调用时,做这件事

When..Do 使用两个调用来配置回调。首先,调用替代实例的 When() 方法来传递一个函数。该函数的参数是替代实例自身,然后此处我们可以调用我们需要的成员,即使该成员返回 void。然后再调用 Do() 方法来传递一个回调,当替代实例的成员被调用时,执行这个回调。

复制代码
 1     public interface IFoo
 2     {
 3       void SayHello(string to);
 4     }
 5 
 6     [TestMethod]
 7     public void Test_CallbacksWhenDo_UseWhenDo()
 8     {
 9       var counter = 0;
10       var foo = Substitute.For<IFoo>();
11 
12       foo.When(x => x.SayHello("World"))
13         .Do(x => counter++);
14 
15       foo.SayHello("World");
16       foo.SayHello("World");
17       Assert.AreEqual(2, counter);
18     }
复制代码

传递给 Do() 方法的参数中包含的调用信息与传递给 Returns() 回调的参数中的相同,这些调用信息可以用于对参数进行访问。

注意,我们也可以对非 void 成员使用 When..Do 语法,但是,通常来说更加推荐 Returns() 语法,因为其更加简洁明确。你可能会发现,对于非 void 函数,当你想执行一个函数而不改变之前的返回值时,这个功能是非常有用的。

复制代码
    [TestMethod]
    public void Test_CallbacksWhenDo_UseWhenDoOnNonVoid()
    {
      var calculator = Substitute.For<ICalculator>();

      var counter = 0;
      calculator.Add(1, 2).Returns(3);
      calculator
        .When(x => x.Add(Arg.Any<int>(), Arg.Any<int>()))
        .Do(x => counter++);

      var result = calculator.Add(1, 2);
      Assert.AreEqual(3, result);
      Assert.AreEqual(1, counter);
    }
复制代码

为每个参数创建回调

如果在某些地方,我们仅需要对一个特殊的参数创建回调,则我们可能会使用为每个参数创建回调的方法,例如 Arg.Do() 和 Arg.Invoke(),而不是使用 When..Do。

参数回调给予我们更加简洁的代码,NSubstitute 中的其他 API 也保持这一风格。更多信息和示例,请查看在参数上执行操作一节。

NSubstitute 完全手册

posted @   sangmado  阅读(2405)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示