Подтвердить что ты не робот

Использование 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));

4b9b3361

Ответ 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));