【问题标题】:Verify that a method with particular parameters was not called using TypeMock验证没有使用 TypeMock 调用具有特定参数的方法
【发布时间】:2011-08-17 15:14:25
【问题描述】:

我正在使用 Typemock 进行一些单元测试。我已经模拟了静态类 Widget。我想模拟 Widget.GetPrice(123) 的返回值来返回值 A。

Isolate.Fake.StaticMethods<Widget>();
Isolate.WhenCalled(() => Widget.GetPrice(123)).WillReturn("A");

我还想验证是否未调用 Widget.GetPrice(456)。

Isolate.Verify.WasNotCalled(() => Widget.GetPrice(456));

WasNotCalled 似乎没有考虑参数。测试回来说它失败了 b/c Widget.GetPrice 实际上被调用了。

我能想到的唯一方法是调用 DoInstead 并在调用 Widget.GetPrice(456) 时增加一个计数器。测试结束时将检查计数器是否增加。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: c# unit-testing static-methods typemock


    【解决方案1】:

    有几种方法可以做到这一点。

    首先,您的 DoInstead 想法非常好,但我会对其进行调整以包含断言:

    Isolate.WhenCalled(() => Widget.GetPrice(0)).DoInstead(
      context =>
      {
        var num = (int)context.Parameters[0];
        Assert.AreNotEqual(456, num);
        return "A";
      });
    

    这里的想法是,当调用该方法时,您在调用时验证传入参数是否符合您的预期,如果不是,则使用 Assert 语句使测试失败。

    (您还会注意到我将“0”作为参数输入,因为正如您所注意到的,实际值并不重要。我发现当参数不使用时,使用 null/0/etc 对未来的维护来说更容易'没关系,所以你不会“忘记”或“被愚弄”认为它确实很重要。)

    您可以做的第二件事是使用 WithExactArguments 来控制行为。

    // Provide some default behavior that will break things
    // if the wrong value comes in.
    Isolate
      .WhenCalled(() => Widget.GetPrice(0))
      .WillThrow(new InvalidOperationException());
    
    // Now specify the right behavior if the arguments match.
    Isolate
      .WhenCalled(() => Widget.GetPrice(123))
      .WithExactArguments()
      .WillReturn("A");
    

    “WithExactArguments”将使您的行为在参数匹配时运行。当你运行你的测试时,如果传入了一个无效的值,就会抛出异常并且测试会失败。

    无论哪种方式,您最终都会使用“WhenCalled”部分来处理您的断言,而不是“Verify”调用。

    【讨论】:

      【解决方案2】:

      免责声明,我在 Typemock 工作。

      由于我们的 API 不断改进,请查看其他解决方案来解决您的问题。你可以使用

      Isolate.WhenCalled((<type arg1>, <type arg1>) => fake<method> (<arg1>, <arg2>)).AndArgumentsMatch((<arg1>, <arg2>) => <check>.<behavior>;
      

      为你想要的参数设置你的行为。

      另外,不需要抛出任何异常。使用如下所示的 DoInstead() 来验证哪个方法没有使用精确的参数调用。不需要内部断言。

      [TestMethod, Isolated]
      public void TestWidget()
      {
          Isolate.WhenCalled((int n) => Widget.GetPrice(n)).AndArgumentsMatch((n) => n == 123).WillReturn("A");
      
          bool wasCalledWith456 = false;
      
          Isolate.WhenCalled(() => Widget.GetPrice(456)).WithExactArguments().DoInstead((context) =>
          {
              wasCalledWith456 = true;
              context.WillCallOriginal();
              return null;
          });
      
          Assert.AreEqual("A", Widget.GetPrice(123));
          Widget.GetPrice(234);
          Widget.GetPrice(345);
          Widget.GetPrice(456);
      
          Assert.IsFalse(wasCalledWith456);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多