2013-02-15 2 views
8

Натолкнулся на какое-то интересное поведение - Assert был пойман Catch блок.Assert in Try..Catch block пойман

List<Decimal> consArray = new List<decimal>(); 
try 
{ 
    Decimal d; 
    Assert.IsTrue(Decimal.TryParse(item.Value, out d)); 
    consArray.Add(d); 
} 
catch (Exception e) 
{ 
    Console.WriteLine(item.Value); 
    Console.WriteLine(e); 
} 

Утверждай бросает AssertFailedException и его поймали catch. Всегда считалось, что если Assert сбой, тест не выполняется, а последовательное выполнение прерывается. Но в этом случае тест проходит. Если ничего плохого произойдет позже - я получаю зеленый тест! В теории - это правильное поведение?

Отредактировано: Я понимаю, что, возможно, это ограничение .NET и как утверждается в MsTest. Исправлено исключение. Начиная с catch - ловит все, что улавливает исключение assert. Но правильно ли это в теории или конкретно в MsTest?

ответ

4

NUnit будет делать то же самое. Как и любые другие рамки тестирования, я думаю, но я знаю только MStest и NUnit в C#.

Я ожидаю, что ваш тестовый код не будет содержать Decimal.TryParse, но ваша бизнес-логика сделает это, что вы проверили бы с помощью объекта и вызова метода.

Что-то вроде:

var sut = new Sut(); 
var d = sut.DoSomethingThatReturnsTheDecimal(item.Value); 

Assert.AreEqual(0.123, d, string.Format("passed value can not be parsed to decimal ({0})", item.Value); 

Для того, чтобы остаться немного ближе к реализации:

List<Decimal> consArray = new List<decimal>(); 

Decimal d = Decimal.MinValue; 

// You don't need to try-catch a Decimal.TryParse 
// Decimal.TryParse(item.Value, out d)); 

try 
{ 
    d = Decimal.Parse(item.Value) 
} 
catch 
{ 
    // Handle exception 
} 

Assert.AreEqual(0.123, d); 

// Does the list add anything at all? In this sample it seems a bit redundant 
consArray.Add(d); 

Во всяком случае, чтобы ответить на ваш вопрос. Предполагается, что уловка поймает ваш AssertFailedException.

PS: Захват AsserFailedException и повторное бросание также будут работать, но для меня это немного странно. Я бы постарался оставить Assert за пределами любых блоков try-catch. Но это может быть только мое мнение, о котором вы не просили :).

+0

Это была шип-логика, которая будет перенесена в метод. В любом случае, обратите внимание на себя - не используйте try..catch в MsTest. Интересно, как это происходит в других тестовых средах - Java, PHP. – nikita

+0

Ах, извините, что вы имели в виду C# frameworks. Java давно, но довольно уверен, что он делает то же самое. Совет. Обновите вопрос с информацией о том, что вас интересует Java, PHP и т. Д. Gl с вашим ответом и счастливым кодированием :) – bas

5

Ваш код работает как ожидалось. Когда Assert терпит неудачу, он выдает AssertFailedException, который наследует от Exception. Поэтому вы можете добавить try-catch и поймать его.

В вашем случае добавьте throw в конце catch и повторно выбросите исключение.

+0

Да, я знаю, что он работает, поскольку Assert выдает исключение и ловить его. Просто хочу знать, правильно ли это в теории TDD? Является ли утверждение неудачным, чем тест должен быть красным - не так ли? Является ли это MSTest конкретным поведением? Как насчет других тестовых платформ? – nikita

+1

@nikita: Это не имеет никакого отношения к TDD или MsTest. 'Assert' - это не какой-то специальный член - это просто класс **, как любой другой. Все рамки работают точно так же. На боковом уровне вы не должны использовать 'try-catch' или' Console.WriteLine' в своем ** модульном ** тесте. –

+0

@jimmy_keen Почему бы не 'Console.Writeline'? Действительно заинтересовался .. – nikita

6

Как уже было сказано, это правильное поведение. Вы можете изменить свой код, чтобы получить . Ожидаемое поведение вашего, перехватывая AssertFailedException и перебрасывая его.

 List<Decimal> consArray = new List<decimal>(); 
     try 
     { 
      Decimal d; 
      Assert.IsTrue(Decimal.TryParse(item.Value, out d)); 
      consArray.Add(d); 
     } 
     catch (AssertFailedException) 
     { 
      throw; 
     } 

     catch (Exception e) 
     { 
      Console.WriteLine(item.Value); 
      Console.WriteLine(e); 
     }