Hallo Timo,
ExpectedException(typeof(Exception)) geht nicht. Es kommt zu folgender Fehlermeldung:
UTA017: ContractTests.SomeClassTest.EnsuresAndResultDemoTest has invalid ExpectedException attribute. The type must inherit from Exception.
Ich denke das ist "by Design", denn so wie man bei einem Try/Catch-Block nach Möglichkeit spezifische Exceptions abfangen soll, ist es auch bei Unit Tests angebracht.
Du hast mir aber den Schubs in die korrekte Richtung gegeben. Der Test sieht jetzt so aus und macht was er soll:
public void EnsuresAndResultDemoTest()
{
var target = new SomeClass();
int someValue = 2;
try
{
target.EnsuresAndResultDemo(someValue);
}
catch(Exception exc)
{
Console.WriteLine(exc.GetType().Name);
Assert.IsTrue(exc.GetType().Name == "ContractException");
return;
}
Assert.Fail("ContractException has not been thrown.");
}
Weil SetHandled das Werfen der ContractException abstellt, muß nur der EventHandler leicht modifiziert werden.
static void OnContractFailed(object sender, ContractFailedEventArgs e)
{
e.SetHandled();
Console.WriteLine(e.Condition + ": " + e.Message);
e.SetUnwind();
}
Mit SetUnwind wird die Exception wieder geworfen.
Ich hab mal irgendwo gelesen daß Try/Catch in einer Testmethode vermieden werden sollte (eben auch weil es ein Zeichen für unwägbaren code under test ist), aber das hier könnte ein Ausnahmefall sein.
Falls du CodeContracts nicht kennst, schau dir das API mal an, ist ne tolle Sache.
CodeContracts
Ausführlicher hier:
CodeContracts
Es gibt zwei kommerzielle Lizenzen und eine freie akademische, die aber ziemlich versteckt ist. Darum hier ein Extra-Link.
Download der freien academic version mit static checker.
CodeContracts ist auch im .net Framework 4 enthalten.