2013-12-10 3 views
6

Мне нужно написать модульный тест для следующей функции, и я увидел, что я могу использовать [ExpectedException]ExpectedException Утверждай

это функция, которая будет проверена.

public static T FailIfEnumIsNotDefined<T>(this T enumValue, string message = null) 
     where T:struct 
    { 
     var enumType = typeof (T); 

     if (!enumType.IsEnum) 
     { 
      throw new ArgumentOutOfRangeException(string.Format("Type {0} is not an Enum, therefore it cannot be checked if it is Defined not have defined.", enumType.FullName)); 
     } 
     else if (!Enum.IsDefined(enumType, enumValue)) 
     { 
      throw new ArgumentOutOfRangeException(string.Format("{1} Value {0} is not does not have defined value in Enum of type {0}. It should not be...", enumType.FullName, message ?? "")); 
     } 

     return enumValue; 
    } 

и здесь будет идти код для проверки исключений, которые должны быть кинул

[TestMethod] 
    [ExpectedException(ArgumentOutOfRangeException(ArgumentException), "message")] 
    public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum() 
    { 
     // PREPARE 
     // EXECUTE 
     // ASSERT 
    } 

Я не имею понятия должны сделать Assert для исключения либо.

+1

Используйте 'Assert.Throws()' вместо 'ExpectedException', так как этот атрибут делает тест пройденным, если exc eption произошло в любой части кода метода тестирования. «Assert.Throws» позволяет проверить точное место кода, в котором происходит исключение. – sthotakura

+0

@sthotakura MSTest не имеет Assert.Throws, если вы не пишете пользовательский, который в любом случае является предпочтительной обработкой исключений MSTest. Подобно NUnit :) В моем ответе есть ссылка – Spock

+0

@Spock Я этого не знал, спасибо! – sthotakura

ответ

17

ExpectedException просто утверждает, что исключение из указанного типа будет выброшен по методе испытаний:

[TestMethod] 
[ExpectedException(typeof(ArgumentOutOfRangeException))] 
public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum() 
{ 
    // PREPARE 
    // EXECUTE 
    // NO ASSERT!! 
} 

Если вы хотите, чтобы утверждать другие параметры исключения, то вы должны использовать try..catch в вашем методе испытаний:

[TestMethod]  
public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum() 
{ 
    // PREPARE 

    try 
    { 
     // EXECUTE 
     Assert.Fail() 
    } 
    catch(Exception exception) 
    {   
     // ASSERT EXCEPTION DETAILS 
    } 
} 

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

public TException AssertCatch<TException>(Action action) 
    where TException : Exception 
{ 
    try 
    { 
     action(); 
    } 
    catch (TException exception) 
    { 
     return exception; 
    } 

    throw new AssertFailedException("Expected exception of type " + 
            typeof(TException) + " was not thrown"); 
} 

Использование:

var exception = AssertCatch<ArgumentOutOfRangeException>(() => /* EXECUTE */); 
Assert.AreEqual("foo", exception.Message); 
2

Вы должны использовать ExpectedException по-разному:

[TestMethod] 
[ExpectedException(typeof(ArgumentOutOfRangeException))] 
public void MyTestSomething() 

, а затем код тест, так что ожидаемое исключение брошено.

0

Вам не нужно утверждать, что если вы используете атрибут ExpectedException, на самом деле ваш код не сможет прийти к утверждению.

взгляд: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx

Если вы хотите быть уверены, что исключение следует положить Assert.Fail() после операции, которая должна бросить исключение, в этом случае, если исключение не выдается, тест завершится неудачно.

1

Возможно, вы захотите найти дополнительную настройку обработки исключений. MSTest ExpectedException attr имеет несколько недостатков. Попытайтесь использовать подход this, который дает вам прекрасный контроль над выброшенным исключением.

1

Утверждай исключением является забросить с правильным сообщением исключения с:

var ex = Assert.Throws<Exception>(() => _foo.DoSomething(a, b, c)); 
Assert.That(ex.Message, Is.EqualTo("Your exception message")); 
1

Хотя ExpectedException не может быть использован как есть, чтобы проверить сообщение, за исключением, вы могли бы реализовать свою собственную логику проверки исключение, унаследовав от ExpectedExceptionBaseAttribute:

Внедрение собственной ожидаемой проверки исключений.Вы можете указать дополнительную информацию и требования, встроенные в методы класса ExpectedExceptionAttribute не может обрабатывать, такие как следующее:

  • Проверка состояния исключения.
  • Ожидание более одного типа исключения.
  • Отображает пользовательское сообщение при возникновении неправильного типа исключения.
  • Контроль результата отрицательного теста.

В вашем случае, это может выглядеть примерно так:

public sealed class ExpectedExceptionMessageAttribute<T> : ExpectedExceptionBaseAttribute 
{ 
    readonly string _expectedMessage; 
    public ExpectedExceptionMessageAttribute(string expectedMessage) 
    { 
     _expectedMessage = expectedMessage; 
    } 

    protected override void Verify(System.Exception exception) 
    { 
     // Handle assertion exceptions from assertion failures in the test method 
     base.RethrowIfAssertException(exception); 

     Assert.IsInstanceOfType(exception, typeof(T), "wrong exception type"); 
     Assert.AreEqual(_expectedMessage, exception.Message, "wrong exception message"); 
    } 
} 

сказавший, что, я бы до сих пор склонны использовать прямой try - catch подход, хотя, как это более конкретные где, как ожидается, будет выбрано исключение:

public static void Throws<T>(Action action, Predicate<T> predicate = null) 
        where T : Exception 
{ 
    try 
    { 
     action(); 
    } 
    catch (T e) 
    { 
     if (predicate == null || predicate(e)) 
     { 
      return; 
     } 

     Assert.Fail($"Exception of type {typeof(T)} thrown as expected, but the provided predicate rejected it: {e}"); 
    } 
    catch (Exception e) 
    { 
     Assert.Fail($"Expected exception of type {typeof(T)} but a different exception was thrown: {e}"); 
    } 

    Assert.Fail($"No exception thrown, expected {typeof(T)}"); 
} 
Смежные вопросы