Warum löst FakeItEasy diese Ausnahme aus, und warum wird die Methode durch die Methode virtuell repariert?

8

Ich habe einen Test (Code ist unten) um zu testen, dass Methode1 Methode2 aufruft. Die Ausnahme, die ich bekomme, ist

  

Der aktuelle Proxy-Generator kann die angegebene Methode nicht abfangen   Der folgende Grund: - Versiegelte Methoden können nicht abgefangen werden.

Die zu testende Methode ist nicht selbst versiegelt. Es hat jedoch eine -Abhängigkeit für eine versiegelte Klasse (eine Drittanbieter-Klasse, für die ich Probleme beim Erstellen eines Wrappers habe, um es richtig zu verhöhnen - ein anderes Thema für eine andere Frage). Wie auch immer, an diesem Punkt Ich bitte FakeItEasy nicht, die versiegelte Klasse zu verspotten. Und während ich meinen Test debugge, wenn die Abhängigkeit aufgerufen wird, kann ich deutlich sehen, dass ein reales Objekt produziert wird, keine Fälschung.

Und dennoch, angesichts der Fehlermeldung, fühle ich mich irgendwie verbunden.

Außerdem habe ich durch Zufälliger Blog-Beitrag , der die Methode virtuell behebt, behebt das Problem und lässt den Test passieren. Ich habe es versucht und es hat funktioniert. Aber ich bekomme nicht warum es repariert hat, und trotzdem macht es keinen Sinn, die Methode virtuell zu halten. In meinem Fall hat die getestete Klasse keine eigenen Kinder, dh; keine Kinder, die ihre Methoden außer Kraft setzen, daher kann ich keinen Grund sehen, sie virtuell zu machen.

Habe ich falsch gedacht, dass ich keinen Grund habe, die Methode virtuell zu machen?
Versucht FakeItEasy irgendwie, diese versiegelte Klasse zu verspotten?

Ich bin wirklich nicht sicher, wie ich mit diesem Test fortfahren soll.

Mein Test

%Vor%


Verwandte Methoden

%Vor%     
EF0 11.07.2014, 16:41
quelle

3 Antworten

20

Obwohl normalerweise auf den Klassenbereich angewendet, bezieht sich sealed in diesem Fall auf die Unfähigkeit, überschreiben Sie die betreffende Methode. Die Verwendung von sealed mit einer Methode ist nur gültig, wenn es sich bei der Methode um eine override handelt. Methoden, die nicht virtuell sind, können jedoch nicht überschrieben werden und sind daher implizit versiegelt.

Worauf dieser Fehler verweist, ist, dass er keine virtuellen Methoden akzeptieren kann die Tatsache, dass es eine Klasse im Flug erstellt, die von Ihrer Klasse übernommen wurde, um diese Abschnitte zu bearbeiten. Auf einer solchen Ebene kann es weder den Unterschied zwischen einer nicht-virtuellen und versiegelten Methode bestimmen, noch muss es - es kann nicht überschrieben werden und kann daher den entsprechenden Abschnitt nicht einfügen.

    
David 11.07.2014, 16:46
quelle
9

Aravols Antwort ist großartig. Ich fordere Sie auf, es zu akzeptieren und / oder abzustimmen.

Es gibt jedoch einen anderen Ansatz. Machen Sie _service2 eine falsche IService2 .

Dann müssen Sie die Signatur aller Methoden nicht ändern (Schnittstellenmethoden sind immer überschreibbar / abbrechbar). Im Allgemeinen ist es einfacher, Interfaceschnittstellen zu fälschen als konkrete (oder sogar abstrakte) Klassen, und es hat den schönen Effekt, tatsächlich zu testen, dass Ihre kollaborierenden Klassen mit Schnittstellen arbeiten können, nicht notwendigerweise nur mit bestimmten Implementierungen der Schnittstellen.

Während ich hier bin und dieser Teil nicht wirklich mit Ihrem Fehler zusammenhängt, aber vielleicht Ihren Code ein wenig klarer macht, da Sie Service1 testen, würde ich es nicht vortäuschen; Verwenden Sie eine tatsächliche Service1 -Instanz. Dies macht den Lesern klar, was tatsächlich getestet wird. Fälschen des Systems unter Test wird weithin als ein Code-Geruch betrachtet.

Wenn Sie diese beiden Punkte zufällig haben, sieht Ihr SetUp etwas mehr so ​​aus:

%Vor%

Und dein Test sollte bestehen.

    
Blair Conrad 11.07.2014 17:54
quelle
0

Ich habe gerade zwei Tage lang ein fast identisches Problem verfolgt. Blair Conrads oben genannte Lösung des Fälschens auf der Interface-Ebene hat für mich funktioniert und macht auch Sinn:

Wenn die zu testende Klasse nicht von einer anderen Klasse abhängig ist, sollte auch der Test nicht funktionieren. Daher fälschen Sie die Schnittstelle und nicht eine Klasse, die die Schnittstelle implementiert.

    
George Wooding 29.09.2015 13:56
quelle

Tags und Links