2013-06-06 11 views
6

Ich arbeite an etwas Code, der ein Muster der Kapselung aller Argumente zu einer Methode als "Anfrage" -Objekt und die Rückgabe eines "Antwort" -Objekts folgt. Dies hat jedoch einige Probleme verursacht, wenn es darum geht, mit MOQ zu spotten. Zum Beispiel:MOQ Stubbing Eigenschaft Wert auf "Any" -Objekt

public class Query : IQuery 
{ 
    public QueryResponse Execute(QueryRequest request) 
    { 
     // get the customer... 
     return new QueryResponse { Customer = customer }; 
    } 
} 

public class QueryRequest 
{ 
    public string Key { get; set; } 
} 

public class QueryResponse 
{ 
    public Customer Customer { get; set; } 
} 

... in meinem Test Ich mag die Abfrage Stummel der Kunden zurück, wenn der Schlüssel

var customer = new Customer(); 
var key = "something"; 
var query = new Mock<ICustomerQuery>(); 

// I want to do something like this (but this does not work) 
// i.e. I dont care what the request object that get passed is in but it must have the key value I want to give it 

query.Setup(q => q.Execute(It.IsAny<QueryRequest>().Key = key)).Returns(new QueryResponse {Customer = customer}); 

gegeben ist, was ich in MOQ möglich will?

Antwort

11

Was Sie suchen, ist die It.Is<T> Methode, wo Sie eine Matcher-Funktion (Func<T, bool>) für das Argument angeben können.

Zum Beispiel für den Schlüssel Überprüfung:

query.Setup(q => q.Execute(It.Is<QueryRequest>(q => q.Key == key))) 
    .Returns(new QueryResponse {Customer = customer}); 
+0

Schön, danke! – nashwan

0

Ich vermute, Sie dies mit benutzerdefinierten Matchers tun könnte.

Von moq's QuickStart page:

// custom matchers 
mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); 
... 
public string IsLarge() 
{ 
    return Match.Create<string>(s => !String.IsNullOrEmpty(s) && s.Length > 100); 
} 

Ich vermute, Sie könnten eine ähnliche Sache zu tun. Erstellen Sie eine Methode, die Match.Create<QueryRequest> verwendet, um Ihren Schlüssel, z.

public QueryRequest CorrectKey(string key) 
{ 
    return Match.Create<QueryRequest>(qr => qr.Key == key); 
} 

und dann

_query.Setup(q => q.Execute(CorrectKey(key))).Returns(new QueryResponse {Customer = customer}); 

Anmerkung: Ich habe diesen Code nicht versucht, so verzeiht mir, wenn es vollständig bricht.

Oh, und für eine leicht verwandte Eigenwerbung: genau diese Art von Komplexität ist es, was mich an Moq und anderen Spottwerkzeugen stört. Aus diesem Grund habe ich eine Mocking-Bibliothek erstellt, mit der Sie nach Methodenargumenten mit normalem Code suchen können: http://github.com/eteeselink/FakeThat. Es ist jedoch in der Mitte eines großen Refactoring (und Umbenennung) Prozesses, so dass Sie vielleicht den Atem anhalten möchten. Trotzdem würde ich begeistert sein zu hören, was Sie davon halten.

EDIT: Oh, @ nemesv schlug mich dazu, mit einer (wahrscheinlich) besseren Antwort. Ah, gut.