2013-06-06 22 views
6

Sto lavorando su un codice che segue un modello di incapsulare tutti gli argomenti su un metodo come oggetto "richiesta" e restituire un oggetto "risposta". Tuttavia, questo ha prodotto alcuni problemi quando si trattava di deridere con MOQ. Per esempio:Valore di stub della MOQ su oggetto "Qualsiasi"

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

... nel mio test voglio stub la query per restituire al cliente quando la chiave è dato

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

è quello che voglio possibile nel MOQ?

risposta

11

Quello che stai cercando è il metodo It.Is<T> in cui è possibile specificare qualsiasi funzione di corrispondenza (Func<T, bool>) per l'argomento.

Per esempio la verifica per la chiave:

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

Bello, grazie! – nashwan

0

Ho il sospetto che si possa fare questo con Matchers personalizzati.

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

ho il sospetto che si possa fare una cosa simile. Crea un metodo che utilizza Match.Create<QueryRequest> per abbinare la tua chiave, ad es.

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

e poi

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

Nota: non ho provato questo codice, quindi perdonatemi se si rompe del tutto.

Oh, e per qualche auto-promozione lievemente correlata: esattamente questo tipo di complessità è ciò che mi infastidisce di Moq e di altri strumenti di derisione. Questo è il motivo per cui ho creato una libreria di derisione che consente di verificare gli argomenti del metodo con il codice normale: http://github.com/eteeselink/FakeThat. È comunque nel bel mezzo di un importante processo di refactoring (e rinominazione), quindi potresti voler trattenere il respiro. Tuttavia, sarei felice di sentire cosa ne pensi.

EDIT: Oh, @nemesv mi ha battuto con una (probabilmente) risposta migliore. Ah bene.