Frage

Mocking versiegelte Klassen kann ziemlich Schmerzen.Ich habe derzeit zugunsten einer Adapter-Muster um dies zu umgehen, aber etwas zu einfach hält, fühlt sich komisch an.

Also, Was ist der beste Weg, Sie zu verspotten versiegelte Klassen?

Java-Antworten sind mehr als willkommen.In der Tat, würde ich erwarten, dass die Java-community hat sich mit dieser mehr und hat viel zu bieten.

Aber hier sind einige der .NET Meinungen:

War es hilfreich?

Lösung

Meine Allgemeine Faustregel ist, dass Gegenstände, die ich brauche, zu verhöhnen, sollte über eine gemeinsame Schnittstelle zu.Ich denke, das ist die richtige design-Weise und macht die tests viel einfacher (und ist normalerweise das, was Sie erhalten, wenn Sie TDD).Mehr dazu können Sie Lesen in der Google Testing Blog neuester Beitrag (Siehe Punkt 9).

Auch habe ich gearbeitet, hauptsächlich in Java in den letzten 4 Jahren, und ich kann sagen, dass ich an einer hand abzählen kann die Anzahl der Male, die ich erstellt habe, eine endgültige (geschlossene) Klasse.Eine weitere Regel ist hier, ich soll immer einen guten Grund haben, zu versiegeln einer Klasse, im Gegensatz zu die Versiegelung es standardmäßig.

Andere Tipps

Für .NET, Sie könnte so etwas wie TypeMock, verwendet profiling-API und ermöglicht Sie zu Haken in Aufrufe an fast alles.

Ich glaube, dass Maulwürfe, von Microsoft Research, ermöglicht es Ihnen, das zu tun.Aus der Maulwürfe Seite:

Maulwürfe können verwendet werden zu jeder Umweg .NET Methode, einschließlich der nicht-virtuellen/static Methoden in versiegelten Arten.

UPDATE: es ist ein neues framework namens "Fakes" in den kommenden VS-11 Version, die ist entwickelt, um ersetzen Sie Maulwürfe:

Die Fakes Framework in Visual Studio 11 ist die nächste generation der Molen & Stubs, und wird schließlich ersetzen.Fakt ist verschiedenen von Maulwürfe, aber so verschieben von Maulwürfe, um Fälschungen erfordern einige änderungen an Ihrem code.Ein Leitfaden für die migration wird zu einem späteren Zeitpunkt verfügbar.

Anforderungen:Visual Studio 11 Ultimate, .NET 4.5

Das problem mit TypeMock ist, dass es Ausreden, schlechtes design.Nun, ich weiß, dass es ist oft jemand anderes bad-design, es ist versteckte, aber erlauben Sie es in Ihren Entwicklungsprozess kann sehr leicht dazu führen, zu erlauben Ihre eigenen bad-designs.

Ich denke, wenn Sie ein mocking-framework verwenden, sollten Sie eine traditionelle (wie Moq) und erstellen Sie eine Isolierung Schicht rund um die unmockable Sache, und verspotten die Isolierung Schicht statt.

Ich fast immer vermeiden, dass Abhängigkeiten von externen Klassen, die tief in meinem code.Stattdessen würde ich viel lieber mit adapter/Brücke zu Ihnen zu sprechen.So, ich bin im Umgang mit meinen Semantik und die Schmerzen zu übersetzen ist isoliert in einer Klasse.

Es macht es auch einfacher, um meine Abhängigkeiten in die lange laufen.

Ich stieß auf dieses problem vor kurzem und nach dem Lesen / suchen, scheint es keine einfache Möglichkeit, außer verwenden Sie ein anderes tool, wie oben erwähnt.Oder groben Dinge zu behandeln, wie ich es Tat:

  • Erstellen Sie eine Instanz der versiegelten Klasse ohne Konstruktor aufgerufen.
  • System.Laufzeit.Die Serialisierung.FormatterServices.GetUninitializedObject(instanceType);

  • Werte zuweisen, um Ihre Eigenschaften / Felder über Reflexion

  • YourObject.GetType().GetProperty("PropertyName").SetValue(dto, newValue, null);
  • YourObject.GetType().GetField("Feldname").SetValue(dto, newValue);

Ich in der Regel den Weg der Schaffung einer Schnittstelle und Adapter - /proxy-Klasse zu erleichtern Spott der versiegelt Typ.Aber, ich habe auch experimentiert mit überspringen Erstellung der Schnittstelle und die proxy-Typ nicht-versiegelt mit virtuellen Methoden.Dies funktioniert gut, wenn der proxy ist wirklich eine Natürliche Basis, die Klasse kapselt und Nutzer Teil der versiegelten Klasse.

Beim Umgang mit code, der benötigt diese Anpassung, bekam ich müde von der Durchführung der gleichen Maßnahmen zu erstellen die Schnittstelle und proxy-Typ, so dass ich umgesetzt habe eine Bibliothek, um die Aufgabe zu automatisieren.

Der code ist etwas komplizierter als das Beispiel im Artikel, den Sie Referenz, als es erzeugt eine assembly, (statt der Quelle code), ermöglicht für die code-Generierung durchgeführt werden, auf jede Art, und nicht erfordern als viel-Konfiguration.

Für mehr Informationen, bitte beziehen sich auf diese Seite.

Es ist durchaus sinnvoll, zu verhöhnen, eine versiegelte Klasse, weil Sie viele framework-Klassen sind versiegelt.

In meinem Fall bin ich versucht, zu verspotten .Net MessageQueue-Klasse, so dass ich TDD meine anmutige exception handling logic.

Hat jemand Ideen, wie Sie zu überwinden Moq, einen Fehler zu "Ungültigen setup auf einem nicht-überschreibbare Mitglied", bitte lassen Sie 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;
    }

Obwohl seine derzeit nur eine beta-Version, ich denke, es lohnt sich im Auge zu behalten, die shim Merkmal der neuen Fakes framework (Teil - Visual Studio 11 Beta release).

Shim-Typen bieten einen Mechanismus, der Umweg jeder .NET-Methode, um eine benutzerdefinierte delegieren.Shim Arten sind code-generiert durch den Fakes-generator, und Sie Delegaten verwenden, das nennen wir shim Arten, geben Sie die neue Methode Implementierungen.Unter der Haube, shim-Typen verwenden von Rückrufen, die injiziert wurden, die zur Laufzeit in die Methode MSIL Körper.

Persönlich war ich auf der Suche mit dieser zu verspotten, die Methoden auf versiegelten framework-Klassen wie DrawingContext.

Gibt es eine Möglichkeit zu implementieren, die eine versiegelte Klasse von einer Schnittstelle...und verspotten die Schnittstelle statt?

Etwas in mir glaubt, dass versiegelte Klassen ist falsch in den ersten Platz, aber das ist mir einfach :)

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