2013-12-10 6 views
6

Ich brauche einen Unit-Test für die nächste Funktion zu schreiben, und ich sah, die ich verwenden kann [ExpectedException]ExpectedException Assert

ist dies die Funktion getestet werden.

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; 
    } 

und hier würde den Code gehen, um die Ausnahmen zu testen, die

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

warf werden sollen habe ich keine Ahnung haben, entweder die Assertion für die Ausnahmen zu machen.

+1

Verwenden Sie 'Assert.Throws()' anstelle von 'ExpectedException', da dieses Attribut den Test bestanden hat, wenn die exc In jedem Teil des Testmethodencodes ist eine Änderung aufgetreten. 'Assert.Throws' ermöglicht es, den genauen Ort des Codes zu testen, an dem die Ausnahme auftritt. – sthotakura

+0

@sthotakura MSTest hat Assert.Throws nicht, es sei denn, Sie schreiben ein benutzerdefiniertes, welches die bevorzugte MSTest-Ausnahmebehandlung ist. Ähnlich wie NUnit :) Es gibt einen Link in meiner Antwort – Spock

+0

@Spock Ich wusste das nicht, Danke! – sthotakura

Antwort

17

ExpectedException gerade diese Ausnahme bestimmten Typ behauptet wird nach Testmethode ausgelöst:

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

Wenn Sie andere Parameter der Ausnahme geltend machen wollen, dann sollten Sie try..catch in Ihrer Testmethode verwenden:

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

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

Sie können Ihre eigene Methode zum Auslösen der Ausnahme schreiben, um zu vermeiden, den gleichen Testcode immer wieder zu wiederholen:

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"); 
} 

Verbrauch:

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

Sie müssen ExpectedException anders verwenden:

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

und dann Test-Code, so dass die erwartete Ausnahme ausgelöst wird.

0

Sie benötigen keine Assertion, wenn Sie das ExpectedException-Attribut verwenden. Ihr Code sollte tatsächlich nicht in der Lage sein, zur Assertion zu gelangen.

Blick: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx

Wenn Sie die Ausnahme ausgelöst wird sicher sein wollen, sollten Sie eine Assert.Fail() nach dem Betrieb genommen, die die Ausnahme, in diesem Fall, wenn die Ausnahme nicht geworfen werfen sollen, ist, Der Test wird fehlschlagen.

1

Sie möchten wahrscheinlich mehr Ausnahmebehandlung anpassen. MSTest ExpectedException attr hat mehrere Fehler. Verwenden Sie die Methode this, mit der Sie die ausgelöste Ausnahme fein steuern können.

1

Assert Ausnahme ist mit der richtigen Ausnahmemeldung werfen mit:

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

Während ExpectedException nicht verwendet werden kann, wie sie ist die Ausnahme der Nachricht zu überprüfen, können Sie Ihre eigene Exception-Validierungslogik durch Erben von ExpectedExceptionBaseAttribute implementieren könnte:

Durch Implementierung Ihrer eigenen erwarteten Ausnahmeverifizierung.Sie können zusätzliche Informationen und Anforderungen an, die die eingebauten in Methoden der ExpectedExceptionAttribute Klasse kann nicht, wie folgendes behandeln:

  • Überprüfen des Zustands der Ausnahme.
  • Erwartet mehr als eine Art von Ausnahme.
  • Anzeigen einer benutzerdefinierten Nachricht, wenn ein falscher Ausnahmetyp ausgelöst wird.
  • Das Ergebnis eines negativen Tests kontrollieren.

In Ihrem Fall könnte es etwa so aussehen:

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"); 
    } 
} 

gesagt hat, dass, würde ich immer noch den direkten try zu verwenden geneigt sein - catch Ansatz obwohl, wie es präziser in ist Es wird erwartet, dass genau die Ausnahme ausgelöst wird: