首页 > 解决方案 > NSubstitute 模拟一个没有参数的方法以进行多次调用

问题描述

我试图模拟一个没有参数的方法,并在单元测试中多次调用它。这是我的主要代码:

foreach (Device device in deviceList)
{
   ResponseCode response = this.client.GetState(device.Name, out State state);
   DeviceStatus deviceStatus = new DeviceStatus
   {
      Device = device,
      ResponseCode = response,
      State = state
   }
}

以下是我在测试中所做的:

IClient mockClient;
var deviceList = new List<Device>
{
  new Device { Name = "device1" },
  new Device { Name = "device2" },
  new Device { Name = "device3" }
}
this.mockClient.GetState(Arg.Is<string>(x => x == "device1"), out State device1State).
    Returns(x =>
    {
      x[1] = preSetStateForDevice1;
      return ResponseCode.Success;
    });
this.mockClient.GetState(Arg.Is<string>(x => x == "device2"), out State device2State).
    Returns(x =>
    {
      x[1] = preSetStateForDevice2;
      return ResponseCode.Success;
    });
this.mockClient.GetState(Arg.Is<string>(x => x == "device3"), out State device3State).
    Returns(x =>
    {
      x[1] = preSetStateForDevice3;
      return ResponseCode.Success;
    });

在调试中,我发现所有三个 GetState 调用都返回与第一次调用相同的结果。我知道有没有 out 参数的多次返回的帖子或没有 out 参数的单个调用方法的帖子,但我不知道如何使这个没有 out 参数的方法的多次调用有效,请帮助。谢谢!

更新:我还尝试通过调用序列而不是输入值来设置和返回,如下所示:

this.mockClient.GetState(Arg.Any<string>(), out State state).
    Returns(x =>
    {
      x[1] = preSetStateForDevice1;
      return ResponseCode.Success;
    },
    x =>
    {
      x[1] = preSetStateForDevice2;
      return ResponseCode.Success;
    },
    x =>
    {
      x[1] = preSetStateForDevice3;
      return ResponseCode.Success;
    });

它也没有工作

更新:从这篇文章中找到了一种方法:NSubstitute, out Parameters and conditional Returns use ReturnsForAnyArgs 而不是 Returns 在第二个 try 方法中将起作用。虽然不知道为什么...

标签: c#unit-testingnsubstitute

解决方案


参数匹配可能有点棘手outref因为最初指定调用时使用的值会在测试执行期间发生变化。

解决此问题的最可靠方法是使用Arg.Any匹配out参数。例如:

mockClient
  .GetState(Arg.Is<string>(x => x == "device1"), out Arg.Any<State>())
  .Returns(...)

有关为什么这是一个问题的更多信息,请参阅设置outref参数:分配后匹配


推荐阅读