Wie verspottest du eine Sealed-Klasse?

10 answers
  • Für .NET könnten Sie etwas wie TypeMock verwenden, das die API für die Profilerstellung verwendet und dies zulässt Sie können sich an fast alles anrufen.

    28 August 2008
    Ilmari Karonen
  • Ich glaube, dass Moles von Microsoft Research dies zulässt du das zu tun Von der Moles-Seite aus:

    Moles können verwendet werden, um eine beliebige .NET -Methode umzuleiten, einschließlich nicht virtueller / statischer -Methoden in versiegelten Typen.

    UPDATE: Es gibt ein neues Framework namens "Fakes" in der kommenden Version von VS 11, das dafür entwickelt wurde Ersetzen Sie die Moles:

    Das fakes Framework in Visual Studio 11 ist die nächste Generation von Moles & amp; Stubs und wird es irgendwann ersetzen. Fakes unterscheidet sich jedoch von Moles, sodass der Wechsel von Moles zu Fakes einige Änderungen am Code erfordert. Ein Leitfaden für diese Migration wird zu einem späteren Zeitpunkt verfügbar sein.

    Anforderungen : Visual Studio 11 Ultimate, .NET 4.5

    20 November 2012
    Ryan GatesJoshua Conner
  • Meine Faustregel besagt, dass Objekte, die ich verspotten muss, auch eine gemeinsame Benutzeroberfläche haben. Ich denke, das ist in Bezug auf das Design recht und macht Tests viel einfacher (und normalerweise auch, wenn man TDD macht). Weitere Informationen dazu finden Sie im Google Testing Blog letzter Beitrag (siehe Punkt 9).

    Außerdem habe ich in den letzten 4 Jahren hauptsächlich in Java gearbeitet und kann sagen, dass ich zählen kann Zum einen, wie oft ich eine letzte (versiegelte) Klasse erstellt habe. Eine weitere Regel ist, ich sollte immer einen guten Grund haben, eine Klasse zu versiegeln, anstatt sie standardmäßig zu versiegeln.

    09 August 2008
    abyx
  • Das Problem mit TypeMock besteht darin, dass schlechtes Design entschuldigt wird. Nun, ich weiß, dass es oft das schlechte Design eines anderen ist, dass es sich versteckt, aber wenn Sie es in Ihren Entwicklungsprozess einfließen lassen, kann dies sehr leicht dazu führen, dass Sie Ihr eigenes schlechtes Design zulassen.

    >

    Ich denke, wenn Sie ein mockendes Framework verwenden, sollten Sie ein traditionelles Framework (wie Moq) verwenden und eine Isolationsschicht um das nicht zu entsperrende Objekt erstellen und stattdessen die Isolationsschicht simulieren.

    28 August 2008
    Brad Wilson
  • Ich vermeide es fast immer, Abhängigkeiten von externen Klassen tief in meinem Code zu haben. Stattdessen verwende ich lieber einen Adapter / eine Brücke, um mit ihnen zu sprechen. Auf diese Weise beschäftige ich mich mit meiner Semantik, und der Schmerz beim Übersetzen ist in einer Klasse isoliert.

    Es macht es auch einfacher, meine Abhängigkeiten auf lange Sicht zu wechseln.

    11 December 2009
    kyoryu
  • Ich bin kürzlich auf dieses Problem gestoßen und nach dem Lesen / Durchsuchen des Internets scheint es keine einfache Möglichkeit zu geben, außer ein anderes Tool wie oben erwähnt zu verwenden. Oder grobe Behandlung von Dingen wie ich:

    • Instanz der versiegelten Klasse erstellen, ohne dass der Konstruktor aufgerufen wird.
    • System.Runtime.Serialization.FormatterServices.GetUninitializedObject ( instanceType);

    • Weisen Sie Ihren Eigenschaften / Feldern Werte durch Spiegelung zu.

    • YourObject.GetType (). GetProperty ("PropertyName"). SetValue (dto, newValue, null);
    • YourObject.GetType (). GetField ("FieldName"). SetValue (dto, newValue);
    12 May 2015
    hassan
  • Im Allgemeinen gehe ich davon aus, eine Schnittstelle und eine Adapter / Proxy-Klasse zu erstellen, um das Verspotten des versiegelten Typs zu erleichtern. Ich habe jedoch auch mit dem Überspringen der Erstellung der Schnittstelle experimentiert und dafür gesorgt, dass der Proxy-Typ mit virtuellen Methoden nicht versiegelt wird. Dies funktionierte gut, wenn es sich bei dem Proxy tatsächlich um eine natürliche Basisklasse handelt, die die versiegelte Klasse einkapselt und verwendet.

    Beim Umgang mit Code, der diese Anpassung erforderte, wurde ich müde von der Ausführung Dieselbe Aktion zum Erstellen des Schnittstellen- und Proxy-Typs. Daher habe ich eine Bibliothek zum Automatisieren der Aufgabe implementiert.

    Der Code ist etwas komplexer als das in dem Artikel angegebene Beispiel erzeugt eine Assembly (anstelle von Quellcode), ermöglicht die Codegenerierung für jeden Typ und erfordert nicht so viel Konfiguration.

    Weitere Informationen finden Sie unter diese Seite .

    08 December 2009
    Steve Guidi
  • Obwohl es derzeit nur in der Betaversion verfügbar ist, denke ich, dass es sich lohnt, die shim -Funktion des neuen Fakes-Framework (Teil der Beta-Version von Visual Studio 11 ).

    Shim-Typen bieten einen Mechanismus zum Umleiten einer beliebigen .NET-Methode an einen benutzerdefinierten Delegaten. Shim-Typen werden vom Fakes-Generator mit Code generiert. Sie verwenden Delegaten, die als Shim-Typen bezeichnet werden, um die neuen Methodenimplementierungen anzugeben. Unter der Haube verwenden Shim-Typen Callbacks, die zur Laufzeit in die MSIL-Methode der Methode injiziert wurden.

    Ich habe mich persönlich damit beschäftigt, die Methoden zu verspotten auf versiegelten Framework-Klassen wie DrawingContext.

    04 April 2012
    dodgy_coder
  • Gibt es eine Möglichkeit, eine versiegelte Klasse über eine Schnittstelle zu implementieren ... und stattdessen die Schnittstelle zu verspotten?

    Etwas in mir hat das Gefühl, dass das Versiegeln von Klassen falsch ist an erster Stelle, aber das ist nur ich:)

    09 August 2008
    Jon Limjap
  • Es ist absolut sinnvoll, eine versiegelte Klasse zu verspotten, da viele Framework-Klassen versiegelt sind.

    In meinem Fall versuche ich, die MessageQueue-Klasse von .Net zu verspotten Ich kann meine graziöse Ausnahmebehandlungslogik mit TDD versehen.

    Wenn jemand Ideen hat, wie Moqs Fehler in Bezug auf "Ungültige Einrichtung eines nicht überschreibbaren Mitglieds" behoben werden können, lassen Sie es mich wissen.

    code:

         [TestMethod]
        public void Test()
        {
            Queue<Message> messages = new Queue<Message>();
            Action<Message> sendDelegate = msg => messages.Enqueue(msg);
            Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate =
                (v1, v2) =>
                {
                    throw new Exception("Test Exception to simulate a failed queue read.");
                };
    
            MessageQueue mockQueue = QueueMonitorHelper.MockQueue(sendDelegate, receiveDelegate).Object;
        }
        public static Mock<MessageQueue> MockQueue
                    (Action<Message> sendDelegate, Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate)
        {
            Mock<MessageQueue> mockQueue = new Mock<MessageQueue>(MockBehavior.Strict);
    
            Expression<Action<MessageQueue>> sendMock = (msmq) => msmq.Send(It.IsAny<Message>()); //message => messages.Enqueue(message);
            mockQueue.Setup(sendMock).Callback<Message>(sendDelegate);
    
            Expression<Func<MessageQueue, Message>> receiveMock = (msmq) => msmq.Receive(It.IsAny<TimeSpan>(), It.IsAny<MessageQueueTransaction>());
            mockQueue.Setup(receiveMock).Returns<TimeSpan, MessageQueueTransaction>(receiveDelegate);
    
            return mockQueue;
        }
     
    07 April 2010
    Adam Lenda