Несколько Moq It.Is <string>() соответствующие аргументы - PullRequest
63 голосов
/ 03 февраля 2012

С 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 по умолчанию используется второй оператор, а не оценка каждого по существу.

Ответы [ 4 ]

43 голосов
/ 03 февраля 2012

Разве это не смущает? Вы пытаетесь смоделировать метод 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";
}
26 голосов
/ 03 февраля 2012

Если вы хотите ограничить ввод только «Джо» и «Трейси», вы можете указать несколько условий в 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 */);
14 голосов
/ 03 февраля 2012

Вызовы Succesive 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";
});

Если для вас важно подтвердить переданный аргумент, вам также необходимо1006 * вместо It.IsAny<string>(...).

3 голосов
/ 26 июня 2012

Пожалуйста, проверьте Введение в 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");
...