N Подставить условия для выдачи исключения, отличные от параметров

Я использую NSubstitute, чтобы имитировать класс, который использует мой тестируемый метод. Этот фиктивный класс может вызывать конкретное исключение при определенных условиях.

В методе, который я тестирую, есть логика «повторной попытки», которую он выполняет, когда перехватывает это исключение. Я пытаюсь проверить эту логику повторной попытки. Итак, мне нужен конкретный метод этого имитируемого класса, чтобы иногда генерировать исключение, но не в других случаях. К сожалению, метод, который генерирует это исключение, не имеет параметров, поэтому я не могу основывать логику генерирования на параметрах.

Как я могу заставить метод фиктивного объекта генерировать исключение:

A) ... первые N раз он вызывается
или
B) ... на основе параметров какой-то другой метод, который вызывается перед этим
или
C) ... при любых других условиях кроме параметров, переданных в

Чтобы дать вам более четкое представление о том, что я пытаюсь сделать, мой код выглядит примерно так:

IDataSender myDataSender = GetDataSender();
int ID = GetNextAvailableID();
myDataSender.ClearData();
myDataSender.Add(ID,"DataToSend");
bool sendSuccess = false;
while (!sendSuccess)
{
   try
   {
      myDataSender.SendData();
      sendSuccess = true;
   }
   catch (IDCollisionException)
   {
      ID++;
      MyDataSender.ClearData();
      myDataSender.Add(ID,"DataToSend");
   }
}

Итак, мне нужно проверить мою логику повтора, и мне нужно смоделировать это IDCollisionException. Однако я не могу заставить SendData () генерировать исключение каждый раз, иначе цикл повтора никогда не будет успешным.

Что я могу здесь сделать?


person JoeMjr2    schedule 02.02.2015    source источник


Ответы (1)


Если я правильно понял вопрос, вы можете использовать When..Do и закрыть локальную переменную, чтобы получить это поведение.

const int throwUntil = 3;
var callsToSendData = 0;
var dataSender = Substitute.For<IDataSender>();

dataSender
    .When(x => x.SendData())
    .Do(x =>
    {
        callsToSendData++;
        if (callsToSendData < throwUntil)
        {
            throw new DbCollisionException();
        }
    });

Точно так же вы также можете использовать обратные вызовы для локального захвата параметров, переданных другим методам, и доступа к ним внутри блок Do (а не просто счетчик).

person David Tchepak    schedule 02.02.2015
comment
Спасибо. Я не понимал, что макет может ссылаться на локальные переменные метода тестирования. - person JoeMjr2; 03.02.2015