验证是否未使用TypeMock调用具有特定参数的方法

时间:2011-08-17 15:14:25

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

我正在使用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实际上被称为。

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

2 个答案:

答案 0 :(得分:3)

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

首先,你的DoInstead想法非常好,但我会调整它以包含一个断言:

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

有这样的想法,当调用该方法时,您在调用时验证传入的参数是您所期望的,如果不是,则使用Assert语句使测试失败。

(你还要注意我把'#34; 0&#34; in作为参数,因为正如你所注意到的那样,实际值并不重要。我觉得它更容易未来的维护使用null / 0 / etc时参数不重要,这样你就不会忘记&#34;或者愚弄他们认为它确实重要。 )

您可以做的第二件事是使用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");

&#34; WithExactArguments&#34;如果参数匹配,将使您的行为仅运行。运行测试时,如果传入了无效值,则会抛出异常并且测试将失败。

无论哪种方式,你最终都会使用&#34; WhenCalled&#34;部分事情来处理你的断言,而不是&#34;验证&#34;调用

答案 1 :(得分: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);
}