如何使用`Setup` /`Verify`中的`out`参数来模拟类方法?

时间:2018-08-23 10:37:37

标签: c# unit-testing moq out

app.post('/getTopAns', function(req, res) {
 console.log("inside getTopAns ");
 var questionId=req.body.questionId;
 mongoose.model('answers').find({
   questionId:questionId,
   compliance:"Y"
 }, function(err, ansResult){
   for (var i = 0;i<ansResult.length;i++) {
   mongoose.model('users').findOne({
       userId:ansResult[i].userId,
   }, function(err,usrResult){
       var obj = {
           followerLength : usrResult.follower.length,
           upvote : ansResult[i].upvote
       }
    })
    console.log(obj);  
   }
});
})

public class MyClass
{
   public virtual void Method1(string par1, int par2)
   {
      // ...

      var result = new Dictionary<byte, string>();
      for(var i = 0; i < 100; i++)
      {
         if(someCondition) break;
         Method2(par1, out byte res1, out string res2);
         result[res1] = res2;
      }

      // ...
   }

   public virtual void Method2(string par1, out byte res1, out string res2)
   {
      // ...

      res1 = 1;
      res2 = "res2";

      // ...
   }
}

在某些情况下, // 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)); } } 的调用次数不应超过3。测试正在检查,该逻辑是否按具体查询的预期工作。

问题是:没有人能确切知道应该返回哪些值。同样,它可能是一个很大的集合。我猜想Method2在这里是正确的位置,但是它不适用于It.IsAny<>()参数。

这种情况下有东西吗?

2 个答案:

答案 0 :(得分:1)

就像commented上的your own answer一样,在Moq不执行任何匹配的地方,请勿使用It.*匹配器;因为如果这样做,很容易使人们误以为阅读代码的人会期望Moq执行某种参数匹配(事实并非如此,匹配器仅适用于输入参数)。

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

// 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));
//                                                    ^^^^^  ^^^^^^

答案 1 :(得分:0)

我已经通过内联ref个匹配项解决了它。

myClassMock
.Verify(v => 
        v.Method2(It.IsAny<string>(), out It.Ref<byte>.IsAny, out It.Ref<string>.IsAny,),
                  Times.AtMost(3));