C# 如何在模拟类方法的`Setup`/`Verify`中使用`out`参数? 公共类MyClass { 公共虚拟void方法1(字符串par1,int par2) { // ... var result=newdictionary(); 对于(变量i=0;iv.Method1(par1,par2),Times.one); 验证(v=>v.Method2(It.IsAny(),out?,out?),Times.AtMost(3)); } }

C# 如何在模拟类方法的`Setup`/`Verify`中使用`out`参数? 公共类MyClass { 公共虚拟void方法1(字符串par1,int par2) { // ... var result=newdictionary(); 对于(变量i=0;iv.Method1(par1,par2),Times.one); 验证(v=>v.Method2(It.IsAny(),out?,out?),Times.AtMost(3)); } },c#,unit-testing,moq,out,C#,Unit Testing,Moq,Out,根据某些条件,调用Method2的次数不应超过3次。测试正在检查,该逻辑是否按照具体查询的预期工作 问题是:没有人能够确切知道应该返回哪些值。而且,它可能是一个非常大的集合。我想,It.IsAny()应该在这里的正确位置,但它不适用于out参数 这种情况有什么办法吗 我通过内联ref-匹配解决了这个问题 // test class public class MyClassTests { [Fact] public void TestMethod() { st

根据某些条件,调用
Method2
的次数不应超过3次。测试正在检查,该逻辑是否按照具体查询的预期工作

问题是:没有人能够确切知道应该返回哪些值。而且,它可能是一个非常大的集合。我想,
It.IsAny()
应该在这里的正确位置,但它不适用于
out
参数


这种情况有什么办法吗

我通过内联
ref
-匹配解决了这个问题

    // test class
public class MyClassTests
{
   [Fact]
   public void TestMethod()
   {
      string par1 = "value";
      int par2 = 2;
      var myClassMock = new Mock<MyClass>() { CallBase = true };

      myClassMock.Verify(v => v.Method1(par1, par2), Times.Once);
      myClassMock.Verify(v => v.Method2(It.IsAny<string>(), out ?, out ?), Times.AtMost(3));
   }
}
myClassMock
.验证(v=>
v、 方法2(It.IsAny(),out It.Ref.IsAny,out It.Ref.IsAny,),
倍。大气(3));
像I on一样,不要在Moq不会执行任何匹配的地方使用
It.
匹配器;因为如果这样做,阅读代码的人可能很容易被误导,以为Moq将执行某种参数匹配(事实并非如此,匹配器仅适用于输入参数)

使用
It.Ref.IsAny
仍然有效,因为它只不过是
T
类型的静态字段。但您也可以使用任何其他适当类型的字段或变量。这样做——使用另一个变量——将是我的建议,以防止上述问题(误导性代码)

//声明一些伪变量;名字不重要。
字节u;
字符串u;;
//然后使用&忘记它们。
验证(v=>v.Method2(It.IsAny(),out,out),Times.AtMost(3));
//                                                    ^^^^^  ^^^^^^
就像我提到的,用这种方式使用
It
匹配器并没有什么意义,因为Moq只对输入参数执行参数匹配。对
out
参数使用匹配器表明您希望Moq在那里执行匹配,这是误导性的。为了清晰起见,我建议您使用虚拟变量而不是Moq的匹配器。例如,声明一个伪变量
byte
,并将其作为
out
传递;字符串参数也是如此。
    // test class
public class MyClassTests
{
   [Fact]
   public void TestMethod()
   {
      string par1 = "value";
      int par2 = 2;
      var myClassMock = new Mock<MyClass>() { CallBase = true };

      myClassMock.Verify(v => v.Method1(par1, par2), Times.Once);
      myClassMock.Verify(v => v.Method2(It.IsAny<string>(), out ?, out ?), Times.AtMost(3));
   }
}
myClassMock
.Verify(v => 
        v.Method2(It.IsAny<string>(), out It.Ref<byte>.IsAny, out It.Ref<string>.IsAny,),
                  Times.AtMost(3));   
// declare some dummy variables; the names don't matter.
byte _;
string __;

// then use & forget about them.
myClassMock.Verify(v => v.Method2(It.IsAny<string>(), out _, out __), Times.AtMost(3));
//                                                    ^^^^^  ^^^^^^