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

标签 c# unit-testing static-methods typemock

我正在使用 Typemock 进行一些单元测试。我 mock 了静态类小部件。我想模拟 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) 时递增计数器。测试结束时将检查计数器是否增加。有没有更好的方法来做到这一点?

最佳答案

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

首先,您的 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”部分来处理您的断言,而不是“验证”调用。

关于c# - 使用 TypeMock 验证是否未调用具有特定参数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7095177/

相关文章:

c# - 如何在 C# 中有效地返回 SortedList<> 中的第一项和最后一项?

c# - .NET Core 控制台应用程序,如何为每个环境配置 appSettings?

xcode - 如何修复 @testable 导入无法在 xcode 单元测试中加载模块

python - 如何检索对模拟的调用的所有内容?

c# - 从 C# 与 C 对话

c# - 使用 'As' 而不是 (<T>) 进行转换?

visual-studio - 为什么 ReSharper 和内置的 MSTest 运行器会忽略我不应该忽略的测试?

java - 为什么当 getInstance 方法不是静态时抛出 stackOverflowError

java - 谁能解释为什么这两个代码都按此顺序打印输出的原因(静态关键字执行优先级)

python - 使用静态方法而不是函数中的子函数的必要性