Как заставить макет вызвать исключение в первый раз и вернуть значение во второй - PullRequest
7 голосов
/ 27 октября 2011

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

Итакмне нужно что-то похожее на:

myMock = Mock<IFoo>();

myMock.Setup(m => m.Excecute()).Throws<SpecificException>();
myMock.Setup(m => m.Execute());

var classUnderTest = MyClass(myMock);
classUnderTest.DoSomething();

Assert.AreEqual(expected, classUnderTest.Result);

Спасибо за любую помощь, которую вы можете оказать.

Ответы [ 2 ]

15 голосов
/ 27 октября 2011

Это один из способов, основанный на примере Moq QuickStart , возвращающем разные значения при каждом вызове.

var mock = new Mock<IFoo>();
var calls = 0;
mock.Setup(foo => foo.GetCountThing())
    .Returns(() => calls)
    .Callback(() =>
     {
        calls++;
        if (calls == 1)
        {
            throw new InvalidOperationException("foo");
        }
     });

try
{
    Console.WriteLine(mock.Object.GetCountThing());
}
catch (InvalidOperationException)
{
    Console.WriteLine("Got exception");
}

Console.WriteLine(mock.Object.GetCountThing());

Если метод возвращает void, используйте:

var myMock = new Mock<IFoo>();
bool firstTimeExecuteCalled = true;

myMock.Setup(m => m.Execute())
      .Callback(() =>
       {
            if (firstTimeExecuteCalled)
            {
                firstTimeExecuteCalled = false;
                throw new SpecificException();
            }
       });

try
{
    myMock.Object.Execute();
}
catch (SpecificException)
{
    // Would really want to call Assert.Throws instead of try..catch.
    Console.WriteLine("Got exception");
}

myMock.Object.Execute();
Console.WriteLine("OK!");
1 голос
/ 27 октября 2011

Почему бы не написать собственный тестовый объект, который это делает?Если это просто будет использоваться для тестирования, например, что-то вроде:

public class Mock : IFoo
{
     private int _calls;

     public Mock()
     {
         _calls = 0;
     }

     public int Execute()
     {
         _calls++;

         if (_calls == 1)
             throw new Exception();

         return value;

     }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...