2015-11-24 14 views
46

Sto scrivendo alcuni test di unità con NUnit 3.0 e, a differenza di v2.x, ExpectedException() è stato rimosso dalla libreria.NUnit 3.0 e Assert.Throws

In base alla risposta this, posso sicuramente vedere la logica nel tentativo di rilevare in modo specifico dove nel test si prevede che il loro sistema generi un'eccezione (piuttosto che dire "ovunque nel test").

Tuttavia, tendo ad essere molto esplicito sui passaggi Arrange, Act e Assert e questo rappresenta una sfida.

ho usato per fare qualcosa di simile:

[Test, ExpectedException(typeof(FormatException))] 
public void Should_not_convert_from_prinergy_date_time_sample1() 
{ 
    //Arrange 
    string testDate = "20121123120122"; 

    //Act 
    testDate.FromPrinergyDateTime(); 

    //Assert 
    Assert.Fail("FromPrinergyDateTime should throw an exception parsing invalid input."); 
} 

Ora ho bisogno di fare qualcosa di simile:

[Test] 
public void Should_not_convert_from_prinergy_date_time_sample2() 
{ 
    //Arrange 
    string testDate = "20121123120122"; 

    //Act/Assert 
    Assert.Throws<FormatException>(() => testDate.FromPrinergyDateTime()); 
} 

Questo non è terribile, ma intorbida la legge e affermare, a mio parere. (Ovviamente, per questo semplice test, non è difficile da seguire, ma potrebbe essere più impegnativo nei test più grandi).

Ho avuto un collega suggeriscono mi libero di Assert.Throws del tutto e solo fare qualcosa di simile:

[Test] 
public void Should_not_convert_from_prinergy_date_time_sample3() 
{ 
    //Arrange 
    int exceptions = 0; 
    string testDate = "20121123120122"; 

    //Act 
    try 
    { 
     testDate.FromPrinergyDateTime(); 
    } 
    catch (FormatException) { exceptions++;} 

    //Assert 
    Assert.AreEqual(1, exceptions); 
} 

Qui, mi attengo con il formato AAA severo, ma a scapito di ancora più gonfiare.

Quindi la mia domanda va ai tester tipo AAA: come faresti una sorta di test di validazione delle eccezioni come sto cercando di fare qui?

+1

Quando collaudato metodo non ha parametri Assert può essere semplificata simili: Assert.Throws (testDate.FromPrinergyDateTime) o Assert.That (testDate.FromPrinergyDateTime, Throws.TypeOf ()); – user3285954

+0

La seconda parte non mi sembra così gonfia? –

risposta

46

Vedo da dove vieni, anche se in questo caso non mi dispiace combinare i passaggi di Act/Assert.

L'unica cosa che mi viene in mente è quello di memorizzare il delegato effettivo (qui per FromPrinergyDateTime) in una variabile come il passo "agire" e poi affermare che:

[Test] 
public void Should_not_convert_from_prinergy_date_time_sample2() 
{ 
    //Arrange 
    string testDate = "20121123120122"; 

    //Act 
    ActualValueDelegate<object> testDelegate =() => testDate.FromPrinergyDateTime(); 

    //Assert 
    Assert.That(testDelegate, Throws.TypeOf<FormatException>()); 
} 

ottengo che "l'atto" il passo non è davvero recitazione, ma piuttosto la definizione di ciò che l'azione è. Tuttavia, delinea chiaramente quale azione è stata testata.

+0

Ah, questa è un'idea carina. Mi stavo impiccando su come separare i due. – Killnine

+2

uomo, vorrei aver capito cosa è successo lì – user314321

+2

Ancora non proprio "recitazione" però. Sto solo dichiarando come intendi agire. – JamesFaix

1

È possibile creare un attributo personalizzato in NUnit 3. Ecco il codice di esempio come creare [ExpectedException] Attribute. (ExpectedExceptionExample mostra come implementare un attributo personalizzato per NUnit) https://github.com/nunit/nunit-csharp-samples

16

In C# 7, ci è un'altra opzione (anche se molto simile alle risposte esistenti):

[Test] 
public void Should_not_convert_from_prinergy_date_time_sample2() 
{ 
    void CheckFunction() 
    { 
     //Arrange 
     string testDate = "20121123120122"; 

     //Act 
     testDate.FromPrinergyDateTime(); 
    } 

    //Assert 
    Assert.Throws(typeof(Exception), CheckFunction); 
} 

Blog post on the subject

+3

Voto superiore a causa del fattore "ciò che è effettivamente possibile fare in C#" – CodingBarfield

Problemi correlati