• NSubstitute完全手册(十一)参数匹配器


    参数匹配器可以用于设置返回值检查接收到的调用。它提供了一种指定一个调用或一组调用的方式,这样可以对所有匹配的调用设置一个返回值,或者检查是否接收到了匹配的调用。

    忽略参数

    通过使用 Arg.Any<T>() 可以忽略一个T类型的参数。

     1     public interface ICalculator
     2     {
     3       int Add(int a, int b);
     4       string Mode { get; set; }
     5     }
     6 
     7     [TestMethod]
     8     public void Test_ArgumentMatchers_IgnoringArguments()
     9     {
    10       var calculator = Substitute.For<ICalculator>();
    11 
    12       calculator.Add(Arg.Any<int>(), 5).Returns(7);
    13 
    14       Assert.AreEqual(7, calculator.Add(42, 5));
    15       Assert.AreEqual(7, calculator.Add(123, 5));
    16       Assert.AreNotEqual(7, calculator.Add(1, 7));
    17     }

    在这个例子中,我们设定当任意数与 5 相加时,返回值 7。我们使用 Arg.Any<int>() 来告诉 NSubstitute 忽略第一个参数。

    我们也可以通过这种方法来匹配任意的子类型。
     1     public interface IFormatter
     2     {
     3       void Format(object o);
     4     }
     5 
     6     [TestMethod]
     7     public void Test_ArgumentMatchers_MatchSubTypes()
     8     {
     9       IFormatter formatter = Substitute.For<IFormatter>();
    10 
    11       formatter.Format(new object());
    12       formatter.Format("some string");
    13 
    14       formatter.Received().Format(Arg.Any<object>());
    15       formatter.Received().Format(Arg.Any<string>());
    16       formatter.DidNotReceive().Format(Arg.Any<int>());
    17     }

    参数条件匹配

    通过使用 Arg.Is<T>(Predicate<T> condition) 来对一个T类型的参数进行条件匹配。
     1     [TestMethod]
     2     public void Test_ArgumentMatchers_ConditionallyMatching()
     3     {
     4       var calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Add(1, -10);
     7 
     8       // 检查接收到第一个参数为1,第二个参数小于0的调用
     9       calculator.Received().Add(1, Arg.Is<int>(x => x < 0));
    10       // 检查接收到第一个参数为1,第二个参数为 -2、-5和-10中的某个数的调用
    11       calculator
    12         .Received()
    13         .Add(1, Arg.Is<int>(x => new[] { -2, -5, -10 }.Contains(x)));
    14       // 检查未接收到第一个参数大于10,第二个参数为-10的调用
    15       calculator.DidNotReceive().Add(Arg.Is<int>(x => x > 10), -10);
    16     }

    如果某参数的条件表达式抛出异常,则将假设该参数未被匹配,异常本身会被隐藏。

     1     [TestMethod]
     2     public void Test_ArgumentMatchers_ConditionallyMatchingThrowException()
     3     {
     4       IFormatter formatter = Substitute.For<IFormatter>();
     5 
     6       formatter.Format(Arg.Is<string>(x => x.Length <= 10)).Returns("matched");
     7 
     8       Assert.AreEqual("matched", formatter.Format("short"));
     9       Assert.AreNotEqual("matched", formatter.Format("not matched, too long"));
    10 
    11       // 此处将不会匹配,因为在尝试访问 null 的 Length 属性时会抛出异常,
    12       // 而 NSubstitute 会假设其为不匹配并隐藏掉异常。
    13       Assert.AreNotEqual("matched", formatter.Format(null));
    14     }

    匹配指定的参数 

    使用 Arg.Is<T>(T value) 可以匹配指定的T类型参数。
     1     [TestMethod]
     2     public void Test_ArgumentMatchers_MatchingSpecificArgument()
     3     {
     4       var calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Add(0, 42);
     7 
     8       // 这里可能不工作,NSubstitute 在这种情况下无法确定在哪个参数上应用匹配器
     9       //calculator.Received().Add(0, Arg.Any<int>());
    10 
    11       calculator.Received().Add(Arg.Is(0), Arg.Any<int>());
    12     }

    通常来讲,这个匹配器不是必须的;大部分情况下,我们可以使用 0 来代替 Arg.Is(0)。然而在某些情况下,NSubstitute 无法解析出那个匹配器应用到了那个参数上(实际上,参数匹配器进行的是模糊匹配;而不是直接解析函数的调用)。在这些情况下会抛出一个 AmbiguousArgumentsException,并且会要求你指定一个或多个额外的参数匹配器。大多数情况下你可能不得不为每个参数显式的使用参数匹配器。

    NSubstitute 完全手册

  • 相关阅读:
    访问者模式
    解释器模式
    享元模式
    职责链模式
    中介者模式
    单例模式
    桥接模式
    命令模式
    迭代器模式
    Python 学习笔记15 类
  • 原文地址:https://www.cnblogs.com/gaochundong/p/nsubstitute_argument_matchers.html
Copyright © 2020-2023  润新知