Frage

Ich möchte nur eine ManagementException Ausnahme für einen bestimmten Fehlercode zu handhaben und habe Schwierigkeiten mit dem Unit-Test für sie zu schreiben. Normalerweise würde ich den Test schreiben, so dass es so etwas wie die folgende ist:

Searcher search = MockRepository.GenerateMock<Searcher>(); 
// wrapper for ManagementObjectSearcher

...

search.Expect(s => s.Get()).Throw(new ManagementException());

...

Dies ist jedoch nicht festgelegt, den Error-Code auf die eine, die ich vor allem will, in der Tat ManagementException keinen Konstruktor hat, die diesen Wert festlegt.

Wie kann dies geschehen?

(Beachten Sie, dass ich RhinoMocks als mein Mockframework verwende, aber ich gehe davon aus, dass dieser Rahmen unabhängig ist, alles was ich brauche hier zu wissen, wie eine ManagementException zu schaffen, die einen bestimmten Fehlercode Wert hat auch ich gefunden habe einige Verweise auf. eine System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) Methode online, aber dies scheint nicht öffentlich zugänglich zu sein).

War es hilfreich?

Lösung

Die geringste Anstrengung über diese Hürde bekommen würde eine statische Helfer / Hilfsmethode, die Reflexion zu hacken-Schlitz in dem erforderlichen Fehlercode verwendet. Mit Hilfe des trefflichsten Reflektor, ich sehe, gibt es ein eigenes „Errorcode“ Feld, das nur über internen ctors definierte in ManagementException gesetzt. Also:)

public static class EncapsulationBreaker
   {
      public static ManagementException GetManagementExceptionWithSpecificErrorCode(ManagementStatus statusToBeStuffed)
      {
         var exception = new ManagementException();
         var fieldInfo = exception.GetType().GetField("errorCode", 
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.DeclaredOnly);
         fieldInfo.SetValue(exception, statusToBeStuffed);
         return exception;
      }
   }

überprüft, dass es funktioniert

[Test]
      public void TestGetExceptionWithSpecifiedErrorCode()
      {
         var e = EncapsulationBreaker.GetManagementExceptionWithSpecificErrorCode(ManagementStatus.BufferTooSmall);
         Assert.AreEqual(ManagementStatus.BufferTooSmall, e.ErrorCode);
      }

Obwohl ich in der Regel bei der Reflexion Stirnrunzeln in Tests , das ist einer der seltenen Fälle, wo es gebraucht wird / nützlich.
HTH

Andere Tipps

Leiten Sie eine Klasse von ManagementException und verstecken den Fehlercode Implementierung mit Ihrem eigenen. Haben Sie Ihre Mock Rückkehr dieser Klasse.

Haben Sie eine sehr einfache und kleine Methode oder Klasse, die diese Ausnahme abfängt und erhält den Fehlercode aus ihm heraus, und dann, dass geht auf die Realklasse auf, die die Arbeit der Fall ist. Unter Test, ersetzen Sie diesen Code mit direkt in der realen Klasse vorbei, was Sie würde passieren, wenn Sie diesen Fehlercode erhalten.

Der offensichtlichste Weg ist die Ausnahme, Unterklasse, aber wenn das nicht funktioniert, dann Code, der es fängt, und sofort Ihre eigenen Ausnahme auslöst, die Sie nicht erlauben, dass Code aussetzen würde eine weitere Option sein.

I ManagementException Unterklasse würde und in der Unterklasse des ErrorCode Getter außer Kraft setzen (wenn die normalen Schutzstufen Sie aufhören, dass zu tun, vielleicht Selbstbeobachtung können Sie näher kommen). Jeder Code, der ManagementException Griffe aber nie über Ihre spezifische Unterklasse gehört, sollten Sie Ihre Unterklasse behandeln „als ob“ es war die ManagementException, dass Sie versuchen zu Testzwecken zu simulieren, nachdem alle.

Bearbeiten : Es ist denkbar, dass nur ErrorCode kann nicht außer Kraft gesetzt werden (I Sprachen hassen, die so starr sind, dass sie Tests auf diese Weise zu stoppen, kann aber nicht leugnen, sie existieren ;-). In diesem Fall Dependency Injection können Sie noch sparen - DI einer meiner Lieblings-Muster für den Test ist

.

DI Zweck in der Prüfung ist es, der im Test befindlichen Code von starren Annahmen zu entkoppeln, die Testbarkeit hemmen würde - und das ist genau das, was wir hier haben, wenn auch in einer ungewöhnlichen Form. Ihr im Test befindlichen Code zur Zeit nicht, sagen wir, x.ErrorCode den Fehlercode der Ausnahme x zu erhalten. Sehr gut, muss es dann tun, stattdessen getErrorCode(x) wo getErrorCode ein Delegierter ist, die normalerweise nur return x.ErrorCode tut; und es muss einen Setter für die getErrorCode Delegierten haben, so dass für Testzwecke, können Sie es zu einem Delegierten ändern kann, das tut return 23 (oder was auch immer Fehlercode Wert, den Sie für die Prüfung simulieren wollen).

Details variieren können, aber Dependency Injection (unter anderem) können Sie helfen, zwangsläufig aus dem System (oder aus anderen Bibliotheken und c, die Sie nicht direkt ändern können) bekommen für einige Arten von übermäßiger Steifigkeit in Objekten zu kompensieren, wie in diesem Beispiel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top