Я использую C# с nUnit для модульного тестирования моего проекта, и я пытаюсь написать некоторые модульные тесты, которые обеспечивают выполнение определенного исключения, но мои тесты продолжают терпеть неудачу. После большого количества тестов, чтобы решить эту проблему, мне удалось определить причину этого и создать небольшой пример кода, который показывает мои данные ниже.Почему мои тесты модуля C# для исключений не работают, если я использую try/catch?
Мой блок тестовый код:
[Test]
public void TestExceptionIsRaised()
{
var ex = Assert.Throws<UnauthorizedAccessException>(() => TestExceptionMethod());
StringAssert.Contains("Attempted to perform an unauthorized operation", ex.Message);
}
Мой метод без проверки ошибок:
public void TestExceptionMethod()
{
throw new UnauthorizedAccessException();
}
Теперь, если я бегу, что модульное тестирование с описанным выше способом ... он бросает исключение, NUnit обнаруживает его и проходит тест. Тем не менее, этот код является проблемой, потому что он не имеет обработки ошибок и сбой, если я его выпустим так.
Итак, чтобы решить эту проблему, я добавляю некоторую обработку ошибок в мой метод, как это:
public void TestExceptionMethod()
{
try
{
throw new UnauthorizedAccessException();
}
catch (UnauthorizedAccessException ex)
{
// Do something about the error
}
}
Но теперь, когда я запускаю тест блока он терпит неудачу с этой ошибкой:
Expected: System.UnauthorizedAccessException But was: null
Так вместо того, чтобы выбирать между единичным тестом или правильной обработкой ошибок, я попытался повторить ошибку следующим образом:
public void TestExceptionMethod()
{
try
{
throw new UnauthorizedAccessException();
}
catch (UnauthorizedAccessException ex)
{
// Do something about the error
throw;
}
}
Наконец-то все работает. Единичный тест проходит каждый раз. И мой метод все еще может поймать ошибку и что-то сделать.
Однако из-за того, что я слышал, это не хорошая практика, чтобы повторять ошибки броска, подобные этому ??? Так что мне просто интересно, мое решение «правильно»? Или есть лучший способ модульного тестирования для исключения без необходимости удалять блоки try/catch из исходного метода?
О, я думаю, что я начинаю понимать, что вы имеете в виду. Единственное, что я до сих пор не понимаю, это то, что, прежде чем я начал писать модульные тесты для исключений, я никогда не использовал ключевое слово Throw. Я просто использовал Try {something} Catch (SomeException ex) {MessageBox.Show (ex.Message)}; и это отлично срабатывало, чтобы поймать исключения, даже если я не брошу их в блок catch. Поэтому я не уверен на 100%, почему это сработало, но теперь мне нужно повторно бросить их в блок catch для модульного теста для работы? – Calcolat
@Calcolat: когда вы используете 'Assert.Throws', нужно исключить исключение' must'. Вы использовали 'Assert.Throws' в своем предыдущем модульном тесте? –
Ах, я понял. Нет, я не использовал Assert.Throws раньше. Я только делал обычные модульные тесты, которые не проверяются на какие-либо исключения. Теперь я понимаю, что вы имеете в виду. Если я не тестирую исключения для исключения, мне не нужно повторно выбрасывать исключение. Но если я использую Assert.Throws, исключение должно быть выбрано, поэтому я должен повторно его выбросить. Верный? – Calcolat