c# - setup - Usar Moq para simular un parámetro de constructor Func<> y verificar que se haya llamado dos veces
moq4 c# (3)
A partir de al menos Moq 4.5.28, puede simular y verificar el Func como esperaría que fuera posible. No pude saber cuándo se agregó esta función (según la pregunta original, en algún momento no funcionó).
[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));
}
Tomó la pregunta de este artículo ( Cómo moq un Func ) y la adaptó ya que la respuesta no es correcta.
public class FooBar
{
private Func<IFooBarProxy> __fooBarProxyFactory;
public FooBar(Func<IFooBarProxy> fooBarProxyFactory)
{
_fooBarProxyFactory = fooBarProxyFactory;
}
public void Process()
{
_fooBarProxyFactory();
_fooBarProxyFactory();
}
}
Tengo la necesidad de simular un Func <> que se pasa como un parámetro de constructor, la afirmación de que la función fue llamada dos veces.
Al intentar var funcMock = new Mock<Func<IFooBarProxy>>();
la función var funcMock = new Mock<Func<IFooBarProxy>>();
Moq plantea y excepción, ya que el tipo de función no es simulable.
El problema es que sin burlarse de la función no es posible verificar que la función fue llamada (n) veces. funcMock.Verify( (), Times.AtLeast(2));
No creo que sea necesario usar un simulacro para el Func.
Simplemente puede crear un Func ordinario que devuelva un simulacro de IFooBarProxy
:
int numberOfCalls = 0;
Func<IFooBarProxy> func = () => { ++numberOfCalls;
return new Mock<IFooBarProxy>(); };
var sut = new FooBar(func);
sut.Process();
Assert.Equal(2, numberOfCalls);
Desde Moq v4.1.1308.2120
A partir de esta versión, que fue lanzada algunos meses después de que se hiciera esta pregunta (21 de agosto de 2013), se agregó la funcionalidad para simular un Func<>
. Entonces, con cualquier versión actual de mock, puedes usar var funcMock = new Mock<Func<IFooBarProxy>>();
.
Respuesta original (desactualizada)
Si tiene muchas funciones de devolución de llamada, Actions
, etc., es mejor definir una interfaz auxiliar en sus pruebas y simular esa interfaz. De esta manera, puede utilizar la funcionalidad Moq normal, como configurar valores de retorno, probar argumentos de entrada, etc.
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));