2012-02-03 7 views
49

Z Moq, czy ważne jest, aby mieć więcej niż jeden argument dopasowania?Wiele Moq It.Is <string>() Dopasowanie Argumenty

It.Is<string>() 

W tym przykładzie chcę mockMembershipService wrócić inną ProviderUserKey w zależności od użytkownika dostarczonym.

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 domyślnie przyjmuje drugie oświadczenie zamiast oceniać każdą z nich na podstawie własnych zalet.

Odpowiedz

31

Czy to nie jest mylące? Próbujesz kpić z metody GetUser, ale ustawiasz wartość Returns dla właściwości zwracanej wartości tej funkcji. Należy także podać właściwość typu powrotu na podstawie wyśmiewanej metody.

Oto sposób bardziej jasny sposób:

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

Oto sposób, aby utworzyć mock członkostwa:

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

Następnie napisać metodę ustalania tej nieruchomości:

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

Spróbuję tego krótko, obejrzałem ten film http://thethoughtfulcoder.com/blog/52/Moq-Use-Setup-arguments-parameters-in-the-Returns-of-a-edched-function podczas dodawania odpowiedź, która robi coś podobnego –

+0

powyższy kod nie skompiluje, narzeka na Security.MembershipUser nie zawiera odniesienia do zwrotów, a także o Użytkowniku nie zawierającym definicji dla ProviderUserKey –

+0

Powinieneś odwołać się do zespołu odpowiadającego Security.MembershipUser, jak sądzę. Lub możesz wstrzyknąć zależność dla tworzenia użytkowników dla Ciebie w usłudze MembershipService –

11

Kolejne wywołania instalacji eliminują poprzednie ustawienia.

Można użyć argumentu w zwrotnego powrotnej:

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

Jeśli jest to dla Ciebie ważne, aby twierdzić, argument przekazany, trzeba także It.Is<string>(...) zamiast It.IsAny<string>(...).

+0

powinny mogę spróbować tego w ciągu około 2 godzin. –

+0

Kod zgłasza niezgodność liczby parametrów –

+0

No cóż, myślę, że to dlatego, że konfigurujemy tutaj właściwość ('ProviderUserKey'), podczas gdy argument, na którym próbujemy działać, pochodzi od' GetUser (...) ' . Nie mogę teraz sprawdzić właściwego rozwiązania, ale jeśli zastosujesz się do wskazówek Ufuk, powinno być ok ... – Bartosz

24

Jeśli chcesz ograniczyć wprowadzanie tylko do "Joe" i "Tracy", możesz określić wiele warunków w It.Is<T>(). Coś jak

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

to nie to, że chcę ograniczyć per se, po prostu chcę ocenić, co na wejściu i powrocie pożądanej wydajności :-) –

+0

Bez względu na to, czy to było we właściwym miejscu, pomogło mi to, dzięki @ cadrell0 –

3

Proszę sprawdzić Introduction to Moq > Matching Arguments dokumentację:

// 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"); 
+2

Teraz z więcej doświadczenie w testach jednostkowych, nie polecam tego rodzaju podejścia. Powinniśmy unikać umieszczania logiki w testach jednostek. Inną opcją jest tworzenie oddzielnych testów jednostkowych: jeden dla ** Joe ** i inny dla ** Tracy ** – Jaider