2013-02-06 12 views
18

preso la questione da questo articolo (How to moq a Func) e adattato come la risposta non è corretta.Utilizzando Moq per deridere un parametro del costruttore Func <> e Verifica è stato chiamato due volte

public class FooBar 
{ 
    private Func<IFooBarProxy> __fooBarProxyFactory; 

    public FooBar(Func<IFooBarProxy> fooBarProxyFactory) 
    { 
     _fooBarProxyFactory = fooBarProxyFactory; 
    } 

    public void Process() 
    { 
     _fooBarProxyFactory(); 
     _fooBarProxyFactory(); 
    } 
} 

Ho un bisogno di prendere in giro un Func <> che viene passato come parametro del costruttore, l'asserzione che il func era chiamata due volte.

Quando si tenta di simulare la funzione var funcMock = new Mock<Func<IFooBarProxy>>(); Moq genera ed eccezione in quanto il tipo Func non è mockable.

Il problema è che senza il mocking della funzione non è possibile verificare che la funzione sia stata chiamata (n) volte. funcMock.Verify((), Times.AtLeast(2));

+0

Moq ora supporta ciò che l'OP stava originariamente cercando di fare, vedere la risposta da @ ktam33 – Mike

risposta

27

non credo che sia necessario utilizzare un mock per la Funz.

Si può semplicemente creare un normale Funz te stesso che restituisce una finta di IFooBarProxy:

int numberOfCalls = 0; 
Func<IFooBarProxy> func =() => { ++numberOfCalls; 
            return new Mock<IFooBarProxy>(); }; 

var sut = new FooBar(func); 

sut.Process(); 

Assert.Equal(2, numberOfCalls); 
2

Dal Moq v4.1.1308.2120

A partire da questa versione, che è stato rilasciato qualche mese dopo questa domanda è stato chiesto (21 agosto 2013), la funzionalità per deridere un Func<>has been added. Quindi, con qualsiasi versione attuale di simulazione, è possibile utilizzare var funcMock = new Mock<Func<IFooBarProxy>>();.

Originale (obsoleto) risposta

Se si dispone di un sacco di callback Func 's, Actions, ecc, è meglio definire un'interfaccia aiutante nei test e prendere in giro tale interfaccia. In questo modo è possibile utilizzare la funzionalità normale Moq, come la creazione di valori di ritorno, provando argomenti di input, ecc

interface IFooBarTestMethods 
{ 
    IFooBarProxy FooBarProxyFactory(); 
} 

Uso

var testMethodsMock = new Mock<IFooBarTestMethods>(); 
testMethodsMock 
    .Setup(x => x.FooBarProxyFactory()) 
    .Returns(new Mock<IFooBarProxy>()); 

var sut = new FooBar(testMethodsMock.Object.FooBarProxyFactory); 
testMethodsMock.Verify(x => x.FooBarProxyFactory(), Times.Exactly(2)); 
6

Come di almeno Moq 4.5.28, è possibile simulare e verificare il Func come ci si aspetterebbe di poterlo fare. Non saprei dire quando questa funzione è stata aggiunta (secondo la domanda originale a un certo punto questo non ha funzionato).

[Test] 
public void TestFoobar() 
{ 
    var funcMock = new Mock<Func<IFooBarProxy>>(); 
    var fooBar = new FooBar(funcMock.Object); 
    fooBar.Process(); 
    funcMock.Verify(x => x(), Times.AtLeast(2)); 
} 
Problemi correlati