Moq: установка ложного метода на первый вызов, сбой на втором - PullRequest
35 голосов
/ 12 августа 2011

Какой самый краткий способ использовать Moq для имитации метода, который будет вызывать исключение при первом его вызове, а затем успешно при втором вызове?

Ответы [ 4 ]

46 голосов
/ 12 августа 2011

Я бы использовал Callback и увеличил счетчик, чтобы определить, следует ли генерировать исключение из Callback.

[Test]
public void TestMe()
{
    var count = 0;
    var mock = new Mock<IMyClass>();
    mock.Setup(a => a.MyMethod()).Callback(() =>
        {
            count++;
            if(count == 1)
                throw new ApplicationException();
        });
    Assert.Throws(typeof(ApplicationException), () => mock.Object.MyMethod());
    Assert.DoesNotThrow(() => mock.Object.MyMethod());
}

public interface IMyClass
{
    void MyMethod();
}
17 голосов
/ 21 августа 2017

Начиная с Moq 4.2, вы можете просто использовать встроенный метод SetupSequence() (как указано в комментарии @RichardBarnett).

Пример:

var mock = new Mock<IMyClass>();
mock.SetupSequence(x => x.MyMethod("param1"))
    .Throws<MyException>()
    .Returns("test return");
16 голосов
/ 12 августа 2011

Лучшее, что я до сих пор придумал, это:

interface IFoo
{
    void Bar();
}

[Test]
public void TestBarExceptionThenSuccess()
{
    var repository = new MockRepository(MockBehavior.Default);
    var mock = repository.Create<IFoo>();

    mock.Setup(m => m.Bar()).
        Callback(() => mock.Setup(m => m.Bar())). // Setup() replaces the initial one
        Throws<Exception>();                      // throw an exception the first time

    ...
}
5 голосов
/ 13 августа 2011

У Фила Хаака есть интересное сообщение в блоге о настройке метода для возврата определенной последовательности результатов.Кажется, что это было бы хорошей отправной точкой, если бы потребовалась некоторая работа, потому что вместо последовательности значений определенного типа вам потребуется теперь иметь последовательность результатов, которая может иметь тип T или исключение.

...