Как смоделировать выбрасывание исключения в юнит-тестах? - PullRequest
10 голосов
/ 13 января 2012

Как я могу имитировать исключение, которое выдается в модульных тестах C #?

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

Например:

public void MyMethod()
{  
  try
  {  
  ...  
  }  
  catch(OutOfMemoryException e)
  {
  ...
  }  
  catch(RandomErrorFromDatabaseLayer e)
  {
  ...
  }  
}

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

Редактировать 1: Любая помощь в выполнении того, что я спросил с Moq?

Ответы [ 2 ]

9 голосов
/ 13 января 2012

Вам необходимо создать фиктивный объект, который заменяет реальные объекты, которые могут генерировать эти исключения. Затем вы можете создавать тесты, которые просто выглядят примерно так:

public void ExampleMethod()
{
    throw new OutOfMemoryException();
}

Если вы используете инфраструктуру внедрения зависимостей, это значительно упрощает замену реального кода на фиктивный.

7 голосов
/ 13 января 2012

Вам нужен stub - объект, который будет имитировать определенные условия для вашего кода.В целях тестирования вы обычно заменяете реализацию реального объекта заглушкой (или другим типом поддельного объекта).В вашем случае рассмотрим:

public class MyClass
{
    private IDataProvider dataProvider;

    public void MyMethod()
    {
        try
        {
            this.dataProvider.GetData();
        }
        catch (OutOfMemoryException)
        {
        }
    }
}

Теперь класс, который вы тестируете, должен быть настраиваемым на некотором уровне, чтобы вы могли легко заменить реальную реализацию DataProvider на заглушенную / фальшивую при тестировании (как вы сказали), ты не хочешь уничтожать свою БД - никто не хочет!).Это может быть достигнуто, например, с помощью инжектора конструктора (или фактически любой другой метод инжекции зависимостей ).

Ваш тест тогда тривиален (некоторые выдуманные требования для тестирования при возникновении исключения):

[Test]
public void MyMethod_DataProviderThrowsOutOfMemoryException_LogsError()
{
    var dataProviderMock = new Mock<IDataProvider>();
    dataProviderMock
        .Setup(dp => dp.GetData())
        .Throws<OutOfMemoryException>();
    var myClass = new MyClass(dataProviderMock);

    myClass.MyMethod();

    // assert whatever needs to be checked
}
...