Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用moq验证对带有param参数的函数的调用_C#_Function_Moq - Fatal编程技术网

C# 使用moq验证对带有param参数的函数的调用

C# 使用moq验证对带有param参数的函数的调用,c#,function,moq,C#,Function,Moq,我有一个带有LogTrace(字符串值,params object[]参数)的ILogger接口。现在,我想验证是否调用了LogTrace,并且要记录的字符串是否包含一些id。问题是,可以以不同的方式调用它。例如。 1) 日志跟踪(“MyString”+id) 2) 日志跟踪(“MyString{0}”,id) 等等 Moq是否有一个好方法来验证所有场景?我只能考虑创建一个手工制作的模拟,它将格式化可用于验证的字符串。您可以尝试使用回调,但它会变得相当复杂(未经测试): var mock=new

我有一个带有LogTrace(字符串值,params object[]参数)的ILogger接口。现在,我想验证是否调用了LogTrace,并且要记录的字符串是否包含一些id。问题是,可以以不同的方式调用它。例如。 1) 日志跟踪(“MyString”+id) 2) 日志跟踪(“MyString{0}”,id) 等等


Moq是否有一个好方法来验证所有场景?我只能考虑创建一个手工制作的模拟,它将格式化可用于验证的字符串。

您可以尝试使用
回调
,但它会变得相当复杂(未经测试):

var mock=new mock();
字符串跟踪=null;
mock.Setup(l=>l.LogTrace(It.IsAny(),It.IsAny())
.回调((s1,par)=>
{
trace=string.Format(s1,par);
});
//剩下的测试
Assert.AreEqual(预期,跟踪);

如果<代码> ILogger <代码>有一个小的接口,您可以考虑手动实现一个存根(它将保留所有应该记录的行),并在测试结束时验证它。如果您记录了多行,那么这将是一个更可读的设置

mock.Verify( m => m.LogTrace( It.IsAny<string>(), It.IsAny<object[]>() ) );

此示例显示如何验证参数列表是否为空,是否包含
5
作为类型
int

的唯一参数。我认为这里没有一种简单的方法来完成您需要的操作。问题在于,您需要确保将某些值的组合传递给您的方法,这会导致许多不同的可验证场景:

  • 字符串包含ID,参数包含ID-pass
  • 字符串包含 ID和参数不包含ID-pass
  • 字符串不包含 ID和参数包含ID=pass
  • 字符串不包含ID和 参数不包含ID-失败
但是,Moq不支持可验证方法的不同参数之间的这种条件表达式。一种可能的解决方案是检查是否缺少id,而不是在任一参数中是否存在id。尝试以下方法:

mock.Verify(m => m.LogTrace(
    It.Is<string>(s => !s.Contains(id)), 
    It.Is<object[]>(o => !o.Contains(id))), Times.Never());
mock.Verify(m=>m.LogTrace(
它是(s=>!s.Contains(id)),
It.Is(o=>!o.Contains(id)),Times.Never();
我们在这里要做的是验证是否满足失败条件——也就是说,字符串不包含id,对象数组也不包含id。我们使用Times.Never()来确保这种情况永远不会发生


但是,请记住,代码乍一看可能并不明显;一旦你写了它,一定要正确地解释你的意图。

它变得更加复杂,因为它并不总是一次调用,我也需要验证。我刚刚测试了我的参数是否等于id,但我正在考虑为此编写我自己的存根我知道它已经通过了,但这样我就不知道它是否包含了我想在那里看到的id。我现在就是这样做的,但是如果日志记录方法确实将id作为参数传递,这将不会有帮助,而是执行类似“id=”的操作 + 5. 我只是想让它少一点fragile@IlyaChernomordik例如我不明白。您是否可以编辑您的答案,并包含一个完整的示例,说明您希望接受什么和拒绝什么?这是一个有趣的建议,但很难验证日志记录是否被调用了2次。这只是包括另一个verify()以确保调用了该方法,在这个断言之前或之后。无论您调用LogTrace多少次,此测试都应确保记录的字符串始终包含id。您确实应该编写额外的断言,以确保至少调用一次该方法。
 mock.Verify( m => m.LogTrace( It.IsAny<string>(),
            It.Is<object[]>(ps =>
                ps != null &&
                ps.Length == 1 &&
                ps[0] is int &&
                (int)ps[0] == 5
            ) ) );
mock.Verify(m => m.LogTrace(
    It.Is<string>(s => !s.Contains(id)), 
    It.Is<object[]>(o => !o.Contains(id))), Times.Never());