多重MoqIt.Is<;字符串>;()匹配参数

本文关键字:参数 字符串 MoqIt Is lt 多重 gt | 更新日期: 2023-09-27 18:22:14

对于Moq,拥有多个匹配参数有效吗?

It.Is<string>() 

在本例中,我希望mockMembershipService根据提供的用户返回不同的ProviderUserKey。

mockMembershipService.Setup(
    x => x.GetUser(
      It.Is<string>(
        s => s.Contains("Joe")))
   .ProviderUserKey)
.Returns("1234abcd");

mockMembershipService.Setup(
  x => x.GetUser(
    It.Is<string>(
      s => s.Contains("Tracy")))
  .ProviderUserKey)
.Returns("5678efgh");

SetUp默认使用第二个语句,而不是根据每个语句的优点进行评估。

多重MoqIt.Is<;字符串>;()匹配参数

这不是令人困惑吗?您正在尝试模拟GetUser方法,但为该函数的返回值的属性设置了Returns。您还希望基于模拟方法来声明返回类型的属性。

这里有一种更清晰的方法:

mockMembershipService.Setup(x => x.GetUser(It.IsAny<string>())
                     .Returns<string>(GetMembershipUser);

这里有一个创建成员模拟的方法:

private MembershipUser GetMembershipUser(string s)
{
    Mock<MembershipUser> user =new Mock<MembershipUser>();
    user.Setup(item => item.ProviderUserKey).Returns(GetProperty(s));
    return user.Object;
}

然后编写一个设置该属性的方法:

private string GetProperty(string s)
{
    if(s.Contains("Joe"))
        return "1234abcd";
    else if(s.Contains("Tracy"))
        return "5678efgh";
}

如果您想将输入限制为仅"Joe"answers"Tracy",您可以在It.Is<T>()中指定多个条件。类似的东西

mockMembershipService.Setup(x => x.GetUser(It.Is<String>(s => s.Contains("Joe") 
                                                         || s.Contains("Tracy")))
    .Returns<string>(/* Either Bartosz's or Ufuk's answer */);

Successive Setup调用使以前的设置无效。

您可以在返回回调中使用您的参数:

mockMembershipService.Setup(x => x.GetUser(It.IsAny<string>()).ProviderUserKey).Returns<string>(s =>
{
    if(s.Contains("Joe"))
        return "1234abcd";
    else if(s.Contains("Tracy"))
        return "5678efgh";
});

如果断言传递的参数对您来说很重要,那么您还需要It.Is<string>(...)而不是It.IsAny<string>(...)

请查看Moq>匹配参数文档简介:

// matching Func<int>, lazy evaluated
mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true); 

// matching ranges
mock.Setup(foo => foo.Add(It.IsInRange<int>(0, 10, Range.Inclusive))).Returns(true); 

// matching regex
mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");