Ich arbeite an einigen Test-Automatisierung für einen Dienst, und fand eine nette Möglichkeit, einige gemeinsame Setup-& Verifikation in eine "Sitzung" Klasse zu rollen.Wie kann ich überprüfen, ob bereits eine Ausnahme ausgelöst wurde?
Konzeptionell könnte ein Testfall wie folgt aussehen:
using (var managerSession = new Session(managerRole))
{
// A manager puts some items in warehouse
}
using (var employeeSession = new Session(employeeRole))
{
// An employee moves items from warehouse to store
}
using (var customerSession = new Session(customerRole))
{
// A customer can buy items from the store
}
im Sitzungs Objektkonstruktor ich eine Verbindung mit dem Dienst einrichten ich mit der richtigen Authentifizierung pro Rolle usw. Testen bin, und in der Sitzung Entsorgen() Methode Ich habe einen gemeinsamen Validierungsblock, der zum Beispiel überprüft, dass während der Lebensdauer der Sitzung keine serverseitigen Fehler oder Warnungen aufgetreten sind.
Nun, das ist natürlich eine Art Missbrauch des IDispose-Musters, und wenn der Testcode in einem using-Block eine Ausnahme auslöst UND der Validierungsblock auch eine Ausnahme auslöst, maskiert die zweite Ausnahme die erste.
Konzeptionell wenn wir dieses Szenario haben:
using (var managerSession = new Session(managerRole))
{
Assert.IsTrue(managerSession.DoJob(), "Manager did not do his job");
}
... und die Assertion fehlschlägt oder der Aufruf von managerSession.DoJob() löst eine Ausnahme aus, dann würde ich die Session Dispose() -Methode gerne überspringen sie den Validierungsblock, dh
public void Dispose()
{
if (NoExceptionThrown())
{
Assert.IsFalse(this.serviceConnection.HasErrors(), "Service connection has errors");
}
this.serviceConnection.Dispose();
}
..., so dass die Testmethode versagt nie mit ‚Service-Anschluss hat Fehler‘, wenn er tatsächlich ausfällt mit ‚-Manager nicht seine Arbeit machen‘
Meine Frage ist: Ist es überhaupt möglich, die 'NoExceptionThrown()' Methode hier zu implementieren? Gibt es eine globale Eigenschaft, die überprüft werden kann oder die in Thread.CurrentThread versteckt ist, die verwendet werden könnte?
Update:
Meine Frage ist nicht wie diese :-) Refactoring
ich natürlich dieses Muster stattdessen verwenden könnte:
Session.ForRole(managerRole, (session) => { /* Test code here */ });
Mit der statischen Methode ForRole() definiert wie
public static void ForRole(Role r, Action<Session> code)
{
var session = new Session(r);
try
{
code(session);
Assert.IsFalse(session.serviceConnection.HasErrors());
}
finally
{
session.Dispose();
}
}
Aber ich bin neugierig, ob es einen Weg gibt, den Ausnahmezustand zu ergreifen, wie oben beschrieben.
Zwei Dinge. Erstens, ja, das missbraucht "IDisposable". Verwenden Sie "IDisposable", um "Ich besitze eine nicht verwaltete Ressource, die so bald wie möglich freigegeben werden sollte". Wenn Sie etwas anderes bedeuten, wird Ihr Code schwer lesbar. Zweitens, sind Sie besorgt über * irgendeine * Ausnahme oder nur * nicht abgefangene * Ausnahmen? Angenommen, der Testcode löst eine Ausnahme aus, fängt sie ab und wird normal beendet. Sollte das markiert werden? –
Ah, ich bin nur besorgt über _uncaught_ Ausnahmen. Ich werde die Frage aktualisieren ... – Christoffer
Wie IDisposable missbrauchen: Ich bin eher besorgt über das Fehlen der gemeinsamen Validierung für jede Sitzung als die mögliche Maskierung von Fehlern, so dass diese Frage eher eine "nette zu haben" -Funktion ist. Die tatsächlichen Blöcke des Testcodes sind 10-100 Zeilen des UI-Automatisierungscodes, und wir haben bereits erkannt, dass Fehler unerkannt bleiben, weil einer der Validierungsschritte in einem der Blöcke verpasst wurde (oder im falschen Block gemeldet wurde). – Christoffer