web-dev-qa-db-fra.com

Plusieurs Moq It.Is <string> () Arguments correspondants

Avec Moq, est-il valide d'avoir plus d'un argument de correspondance?

It.Is<string>() 

Dans cet exemple, je souhaite que mockMembershipService renvoie une autre clé ProviderUserKey en fonction de l'utilisateur fourni.

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");

La configuration par défaut correspond à la deuxième instruction au lieu d’évaluer chacune d’elles individuellement.

65
Nicholas Murray

N'est-ce pas déroutant? Vous essayez de simuler la méthode GetUser mais vous définissez les retours pour la propriété de la valeur de retour de cette fonction. Vous souhaitez également indiquer la propriété du type de retour en fonction de la méthode simulée.

Voici un moyen plus clair:

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

Voici une méthode pour créer la maquette d'adhésion:

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

Ensuite, vous écrivez une méthode pour définir cette propriété:

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

Si vous souhaitez limiter la saisie à "Joe" et "Tracy", vous pouvez spécifier plusieurs conditions dans It.Is<T>(). Quelque chose comme

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

Les appels de configuration successifs annulent les configurations précédentes.

Vous pouvez utiliser votre argument dans votre rappel de retour:

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";
});

S'il est important pour vous d'affirmer l'argument passé, vous avez également besoin de It.Is<string>(...) au lieu de It.IsAny<string>(...).

14
Bartosz

Veuillez vérifier Introduction à Moq> Arguments correspondants documentation:

// 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");
3
Jaider