2012-10-13 10 views
25

Ben iki kez Moq ile bir yöntem kurmak istiyorum ama sonuncusu öncekileri geçersiz kılıyor gibi görünüyor. İşte benim ilk kurulum var:Farklı parametreler için bir yöntem iki kez nasıl sahte ile alay

string username = "foo"; 
string password = "bar"; 

var principal = new GenericPrincipal(
    new GenericIdentity(username), 
    new[] { "Admin" }); 

var membershipServiceMock = new Mock<IMembershipService>(); 
membershipServiceMock.Setup(ms => 
    ms.ValidateUser(username, password) 
).Returns(new ValidUserContext { 
    Principal = principal 
}); 

Bu güzel çalışır ancak kullanıcı adı veya şifre yukarıdaki gibi username ve password değişkenler yerine ise bu new ValidUserContext() dönmek istiyorum. Bunu yapmak için, başka bir kurulum eklendi ama her zaman yukarıda birini geçersiz kılar ve bu kez uygular:

membershipServiceMock.Setup(ms => 
    ms.ValidateUser(It.IsAny<string>(), It.IsAny<string>()) 
).Returns(
    new ValidUserContext() 
); 

MOQ ile durumların bu tür taşıma en zarif yolu nedir?

Düzenleme

aşağıda yaklaşımla sorunu çözüldü ama bu işleme daha iyi bir yolu olduğunu tahmin:

var membershipServiceMock = new Mock<IMembershipService>(); 
membershipServiceMock.Setup(ms => 
    ms.ValidateUser(It.IsAny<string>(), It.IsAny<string>()) 
).Returns<string, string>((u, p) => 
    (u == username && p == password) ? 
    new ValidUserContext { 
     Principal = principal 
    } 
    : new ValidUserContext() 
); 

cevap

35

Moq argüman kısıtlamaları ile kutunun dışında bu destekler:

Tümünü yakalaIt.IsAny ayrıca çalışır, ama düzen önemlidir: kutusu seçeneği arasından

// general constraint first so that it doesn't overwrite more specific ones 
mock.Setup(ms => ms.ValidateUser(
     It.IsAny<string>(), It.IsAny<string>()) 
    .Returns(new ValidUserContext()); 
mock.Setup(ms => ms.ValidateUser(
     It.Is<string>(u => u == username), It.Is<string>(p => p == password)) 
    .Returns(new ValidUserContext { Principal = principal }); 
+1

İlk çözüm u == kullanıcı adı ve p! = Parola olduğunda durumu çözmüyor mu? –

2

başka parametrelere bağlı olarak farklı ValidUserContexts dönmek için Return <> sürümünü kullanmaktır. Yukarıdaki cevaptan daha iyi değil, sadece başka bir seçenek.

ValidateUser() işlevini, ValidateUser() adlı kullanıcı adı ve parolayı ileterek GetUserContext (string, string) işlevinin sonucunu döndürmek için kuruyoruz.

[TestClass] 
public class MultipleReturnValues { 

    public class ValidUserContext { 
     public string Principal { get; set; } 
    } 

    public interface IMembershipService { 
     ValidUserContext ValidateUser(string name, string password); 
    } 

    [TestMethod] 
    public void DifferentPricipals() { 

     var mock = new Mock<IMembershipService>(); 
     mock.Setup(mk => mk.ValidateUser(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>(GetUserContext); 

     var validUserContext = mock.Object.ValidateUser("abc", "cde"); 

     Assert.IsNull(validUserContext.Principal); 


     validUserContext = mock.Object.ValidateUser("foo", "bar"); 

     Assert.AreEqual(sPrincipal, validUserContext.Principal); 


    } 

    private static string sPrincipal = "A Principal"; 
    private static ValidUserContext GetUserContext(string name, string password) { 

     var ret = new ValidUserContext(); 

     if (name == "foo" && password == "bar") { 
      ret = new ValidUserContext { Principal = sPrincipal }; 
     } 
     return ret; 

    } 
} 
İlgili konular