Использование Moq для извлечения параметра конструктора Func <> и Verify он был вызван дважды
Взял вопрос из этой статьи (Как moq a Func) и адаптировал его, поскольку ответ неверен.
public class FooBar
{
private Func<IFooBarProxy> __fooBarProxyFactory;
public FooBar(Func<IFooBarProxy> fooBarProxyFactory)
{
_fooBarProxyFactory = fooBarProxyFactory;
}
public void Process()
{
_fooBarProxyFactory();
_fooBarProxyFactory();
}
}
Мне нужно высмеять Func < > , который передается как параметр конструктора, утверждают, что функция func была вызвана дважды.
При попытке издеваться над функцией var funcMock = new Mock<Func<IFooBarProxy>>();
Повышения Moq и исключение, поскольку тип Func не является макетным.
Проблема заключается в том, что без издевательства над func невозможно проверить, что func был вызван (n) раз. funcMock.Verify( (), Times.AtLeast(2));
Ответы
Ответ 1
Я не думаю, что нужно использовать макет для Func.
Вы можете просто создать обычный Func, который возвращает макет IFooBarProxy
:
int numberOfCalls = 0;
Func<IFooBarProxy> func = () => { ++numberOfCalls;
return new Mock<IFooBarProxy>(); };
var sut = new FooBar(func);
sut.Process();
Assert.Equal(2, numberOfCalls);
Ответ 2
Как минимум по Moq 4.5.28, вы можете высмеять и проверить Func, как вы ожидали бы. Я не мог сказать, когда эта функция была добавлена (по первому вопросу в какой-то момент это не сработало).
[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));
}
Ответ 3
Если у вас много обратных вызовов Func
, Actions
и т.д., лучше определить вспомогательный интерфейс в ваших тестах и издеваться над этим интерфейсом. Таким образом, вы можете использовать регулярные функции Moq, такие как настройка возвращаемых значений, тестирование входных аргументов и т.д.
interface IFooBarTestMethods
{
IFooBarProxy FooBarProxyFactory();
}
Использование
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));