2014-12-10 5 views
7

Sto prendendo in giro alcuni oggetti usando Moq e alcuni di essi possono avere oggetti di richiesta di raccolta parametri abbastanza lunghi passati come argomenti.È possibile memorizzare un oggetto di confronto "It" come variabile, invece di definirlo in linea? (Moq)

Per facilità di riutilizzo e stile, mi piacerebbe essere in grado di memorizzare queste richieste, con argomenti specifici, da utilizzare nella configurazione di simulazione. Per esempio:

mockedObject 
    .Setup(mo => 
    mo.GetBobbins(It.Is<GetBobbinsRequest> 
     (r.Parameter1 == value1 && [...] & r.ParameterN == valueN)) 
    .Returns(someBobbins); 

diventa:

var request = It.Is<GetBobbinsRequest> 
    (r.Parameter1 == value1 && [...] & r.ParameterN == valueN); 
mockedObject 
    .Setup(mo => mo.GetBobbins(request)) 
    .Returns(someBobbins); 

Ma questo non sembra funzionare. Ho anche provato:

Func<GetBobbinsRequest> request =() => It.Is<GetBobbinsRequest> 
    (r.Parameter1 == value1 && [...] & r.ParameterN == valueN); 
mockedObject 
    .Setup(mo => mo.GetBobbins(request())) 
    .Returns(someBobbins); 

Ma nessuna gioia neanche lì. C'è un modo per salvare un oggetto stile It come variabile? O mi manca qualche altro modo ovvio per gestirlo?

risposta

5

E ... ho trovato la risposta. È la partita di Moq (classe):

Creare un abbinatore personalizzato è semplice. Hai solo bisogno di creare un metodo che restituisce un valore da una chiamata a creare con il vostro condizione di accordo e facoltativo espressione renda accogliente:

[Matcher] 
public Order IsBigOrder() 
{ 
    return Match<Order>.Create(
     o => o.GrandTotal >= 5000, 
     /* a friendly expression to render on failures */ 
     () => IsBigOrder()); 
} 

Questo metodo può essere utilizzato in qualsiasi invocazione di impostazione finto:

mock.Setup(m => m.Submit(IsBigOrder()).Throws<UnauthorizedAccessException>(); 

http://www.nudoq.org/#!/Packages/Moq/Moq/Match(T)

4

Una rapida spiegazione del motivo per cui ciò che hai nella tua domanda non funziona, dal momento che l'ho scritto prima di vedere la tua risposta:

La chiamata a It.Is termina in realtà returning default(T) every time, quindi archiviarla e utilizzarla in un secondo momento sarebbe lo stesso che basta passare il null o qualunque sia il valore predefinito del tipo di parametro.

Il motivo per cui deve essere in linea è perché la chiamata alla It.Is in realtà funziona setting a static member in a "mock context" che la chiamata a Setupeventuallygetsaround ad usare.

Problemi correlati