2013-02-07 9 views
5

Come si dovrebbe fare per falsificare il seguente:Falsificare un metodo generico FakeItEasy

public interface IBlah 
{ 
    Func<T, bool> ApplyFilter<T>(Func<T, bool> predicate) where T:IMessage; 
} 

Quello che vorrei è per il falso per tornare semplicemente si tratta di argomento senza alcuna modifica. Tuttavia, vorrei verificare che il falso sia stato chiamato esattamente una volta. Un caso d'uso è il seguente:

public class Something 
    { 

    public Something(IBlah blah) { _blah = blah; } 

    public bool DoSomething(SomeValue m, Func<SomeValue, bool> predicate) 
    { 
     Func<SomeValue, bool> handler = _blah.ApplyFilter(predicate); 
     return handler(m); 
    } 
    } 

cioè i bisogni falsi per agire come un passaggio attraverso ma devono anche essere in grado di verificare che è stato utilizzato.

Qual è il modo migliore per farlo?

[Si prega di non preoccuparsi per l'esempio inventato ... ci sono un sacco di cose in corso sotto le coperte, ma ho semplificato verso il basso per l'esempio di cui sopra.]

+1

Vuoi verificare che è utilizzato non più di una volta, usato almeno una volta, o utilizzato una sola volta? Cosa dovrebbe accadere se non soddisfa questa condizione? Questa interfaccia dovrebbe avere una proprietà 'numInvocations'? Puoi verificare che non sarà chiamato * più * di una volta abbastanza facilmente, ma sapendo se non è stato chiamato ... hai bisogno di un modo per fornire feedback. – Servy

+0

Senza generici coinvolti, posso fare lo stesso con var falso = A.Fake (); A.CallTo (() ==> fake.SomeMethod (A ._)) .ReturnsLazily (x => x.GetArgument (0)); .... A.CallTo (fake) .MustHaveHappened (Repeated.Exactly.Once); Non riesco a capire come fare lo stesso con Func generico. Ho provato a creare un'implementazione fittizia dell'interfaccia e questo può fare il passaggio, ma dal momento che è concreto, FakeItEasy non può verificare che sia stato usato. – ashic

+0

Pertanto, è necessario assicurarsi che avvenga esattamente una volta che si desidera che il metodo restituisca una classe con due proprietà, 'NumInvokations' e questa funzione. Passare la funzione altrove, quindi determinare se 'NumInvokations' è uguale a uno in seguito. – Servy

risposta

2

Sarebbe questo risolvere il problema ? Si passerà attraverso il predicato e anche verificare che ApplyFilter è stato chiamato una sola volta

[Fact] 
    public void TestFeature() 
    { 
     var fake = A.Fake<IBlah>(); 
     A.CallTo(() => fake.ApplyFilter(A<Func<int, bool>>.Ignored)).ReturnsLazily(x => 
      { 
       return x.GetArgument<Func<int, bool>>("predicate"); 
      }); 
     var something = new Something(fake); 
     var result = something.DoSomething(1, x => x > 1); 

     Assert.False(result); 
     A.CallTo(() => fake.ApplyFilter(A<Func<int, bool>>.Ignored)).MustHaveHappened(Repeated.Exactly.Once); 
    } 
+0

Mentre funzionerebbe mentre si specifica che T è int, sto cercando una versione generica che dovrebbe funzionare per qualsiasi tipo. Il seguente tipo di spettacoli che sto cercando di ottenere: http://pastebin.com/fJgi6ikj In altre parole, il falso dovrebbe funzionare per * qualsiasi * IMessage, senza dover specificare il tipo esatto. – ashic