Moq - 将参数从 setup() 传递到 returns()

Moq - passing arguments from setup() to returns()

我不确定如何在 Moq 中将参数从 Setup() 传递到 Returns()。

这是一个例子:

public static IInterfaceHandler GetInterfaceHandlerMoq()
{
   // Defining the moq
   var moq = new Mock<IInterfaceHandler>();

   // Trying to set up a moq using another moq
   moq.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid>(), It.IsAny<string>()))
       .Returns((Guid guid, string value) => GetProgrammerMoq(guid, value));

   // Return mocked object
   return moq.Object;
}

请注意,GetProgrammerMoq() 是一个将 return 另一个 Moq 的库。这是代码:

public static IProgrammer GetProgrammerMoq(Guid guid, string instName)
{
    // Create Moq
    var moq = new Mock<IProgrammer>();

    // Set up the returnables
    moq.Setup(o => o.InstanceName).Returns(programmer + "_" + instName);
    moq.Setup(o => o.Guid).Returns(guid);

    // Return mocked object
    return moq.Object;
}

在这里看到,GetProgrammerMoq() 需要根据传递给 CreateCommunicationInterface() 的内容设置其参数。

然后我的测试尝试获取和使用最小起订量,但是“p”被 returned 为 null(因为,我猜,我的参数没有正确传递给 Returns()) .
这是测试的草稿:

[Fact]
public void DoSomething()
{
    IInterfaceHandler test = ProgrammerMoqs.GetInterfaceHandlerMoq();

    Guid? g = new Guid();
    IProgrammer p = test.CreateCommunicationInterface(g, "test-boff");

    ...
}

试试这个:

   var moq = new Mock<IInterfaceHandler>(MockBehavior.Strict);

MockBehavior.Strict:如果你从 Mock 中得到 NULL,那么总是尝试 MockBehavior.Strict。当某些设置未准备时,Moq 默认为 returns NULL。但是对于MockBehavior.Strict,它会抛出异常。每次尝试从模拟对象调用任何东西,如果它缺乏正确的设置,都会抛出。

如果在尝试 MockBehavior.Strict 时遇到异常,则意味着:

.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid>(), It.IsAny<string>()))

未能捕捉到调用,因此模拟 return默认为 NULL。

为什么没有捕捉到调用?有几种选择:

  • CreateCommunicationInterface 可能已过载,并且您的设置匹配了您未预料到的另一个过载
  • 过滤器(It.IsAny..)与实际参数不匹配
  • (..)

Klaus Gütter 在评论中提到 GuidGuid? 的区别。事实上,您使用的过滤器是 It.IsAny() 而在测试中您通过了:

Guid? g = new Guid();

g 不是 Guid 类型的对象,它是 Nullable<Guid>,因此查找 any-Guid 的过滤器不匹配。编译代码,因为表达式It.IsAny<Guid>()的结果符合方法想要的Guid?,但类型仍然不匹配。

如果你尝试 It.IsAny() 它可能会很好地匹配 return 你想要的。

moq.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid?>(), It.IsAny<string>()))
   .Returns((Guid? guid, string value) => GetProgrammerMoq(guid, value));