Autofixture: Behandeln Sie Delegierte mit FakeItEasy als Fakes

Erstellt am 16. Feb. 2018  ·  15Kommentare  ·  Quelle: AutoFixture/AutoFixture

Soweit ich weiß, behandelt AutoFixture Schnittstellen und abstrakte Typen automatisch als Mockables. Ich denke, es ist eine gute Idee, auch die Delegattypen in diese Liste aufzunehmen.

enhancement good first issue

Hilfreichster Kommentar

Veröffentlicht in v4.2.0! Ermöglichen:
c# fixture.Customize(new AutoFakeItEasyCustomization { GenerateDelegates = true });

Alle 15 Kommentare

Könnten Sie bitte zunächst klären, mit welchem ​​Mocking-Framework Sie arbeiten? Wir haben ein paar Integrationen (Moq, NSubsitute, FakeItEasy), daher ist es unklar. Soweit ich weiß, werden Delegierte bereits durch die Moq-Integration unterstützt (zumindest wird das in #742 erwähnt).

Soweit ich weiß, hat AutoFixture auch einen eigenen Mechanismus zur Generierung von Delegaten. Hast du irgendwelche Probleme damit?

@zvirja Ich benutze FakeItEasy. Also ändere ich den Titel der Ausgabe
Der folgende Code gibt einen Fake zurück, nachdem die Anpassung angewendet wurde:
var myFake= fixture.Create<ISomeInterface>();

Folgendes gilt jedoch nicht:
var myFake= fixture.Create<Func<int,int>>();

Der obige Code gibt nur einen nicht gefälschten Dummy-Delegaten zurück.

Weiterhin stürzt folgendes mit einem Fehler ab:

var myFake= fixture.Create<Fake<Func<int,int>>>();

AutoFixture.ObjectCreationExceptionWithPath
HRresult=0x80131500
Message=AutoFixture konnte keine Instanz aus System.IntPtr erstellen, da die Erstellung mit Ausnahme unerwartet fehlgeschlagen ist. Bitte beachten Sie die innere Ausnahme, um die Ursache des Fehlers zu untersuchen.

Anfragepfad:
FakeItEasy.Fake 1[System.Func 2[System.Int32,System.Int32]]
IntPtr-Methode
System.IntPtr

Innere Ausnahmemeldungen:
AutoFixture.Kernel.IllegalRequestException: Eine Anforderung für einen IntPtr wurde erkannt. Dies ist eine unsichere Ressource, die den Prozess abstürzt, wenn sie verwendet wird, sodass die Anforderung abgelehnt wird. Eine häufige Quelle für IntPtr-Anfragen sind Anfragen für Delegierte wie Funcoder Aktion. Wenn dies der Fall ist, besteht die erwartete Problemumgehung darin, den problematischen Typ durch Angabe einer geeigneten Erstellungsstrategie anzupassen (zu registrieren oder einzufügen).

Quelle=
StackTrace:

Innere Ausnahme 1:
IllegalRequestException: Eine Anforderung für einen IntPtr wurde erkannt. Dies ist eine unsichere Ressource, die bei Verwendung zum Absturz des Prozesses führt, sodass die Anforderung abgelehnt wird. Eine häufige Quelle für IntPtr-Anfragen sind Anfragen für Delegierte wie Funcoder Aktion. Wenn dies der Fall ist, besteht die erwartete Problemumgehung darin, den problematischen Typ durch Angabe einer geeigneten Erstellungsstrategie anzupassen (zu registrieren oder einzufügen).

@OnurGumus Ich habe dieses Problem kurz untersucht und es scheint nicht, dass FakeItEasy das Verspotten von Delegierten unterstützt. Delegierte werden in ihrer Dokumentation

Außerdem habe ich den folgenden Code getestet und er ist mit einer Ausnahme fehlgeschlagen (was beweist, dass die Funktion nicht unterstützt wird):
c# A.Fake<Func<int, int>>();

Daher scheint es nicht, dass AutoFixture auch etwas dagegen tun kann.

Könnten Sie das gewünschte Verhalten bitte genauer beschreiben? Es ist sehr einfach, einen Delegaten zu verspotten, da er über einen primitiven Lambda-Ausdruck angegeben werden könnte. Warum also brauchen Sie Mocks?

@zvirja , FakeItEasy unterstützt sicherlich Fakes für Delegierte:
image

@blairconrad Könnten Sie bitte ein paar Minuten finden und etwas Licht ins Dunkel bringen? Unterstützt FakeItEasy die Verspottung der Delegierten? Wenn ja, wie lautet die Syntax? Mein obiges Beispiel ist für mich fehlgeschlagen, aber es kann passieren, dass ich etwas übersehen habe... :confused:

Danke :zwinker:

@zvirja , gerne. Wie @OnurGumus sagt, fälscht FakeItEasy gerne Delegierte (und ich habe ein Problem erstellt, um dies zu dokumentieren).
AutoFakeItEasy hat sich jedoch nie darum gekümmert, Delegierte zu fälschen.

Wenn beispielsweise ein Fake<Func<int, int>> gefälscht wird, schlägt FakeItEasyMethodQuery.SelectMethods fehl, weil es den Fall Fake<T> nicht berücksichtigt, in dem T ein Delegierter ist. Die sehr naive Änderung unten korrigiert dies.

@@ -33,7 +33,7 @@ namespace Ploeh.AutoFixture.AutoFakeItEasy
             }

             var fakeType = type.GetFakedType();
-            if (fakeType.IsInterface)
+            if (fakeType.IsInterface || fakeType.IsSubclassOf(typeof(Delegate)))
             {
                 return new[] { new ConstructorMethod(type.GetDefaultConstructor()) };
             }

Dann kann ich ein Fake<Func<int, int>> erstellen und verwenden.

Was das Erstellen eines Func<int, int> angeht, habe ich es schnell versucht und festgestellt, dass das Gerät DelegateGenerator , um einen (nicht-FakeItEasy) Delegaten zu erstellen.
Zwischen Ihnen und mir war ich immer von der AutoFixture-Architektur und der Beziehung zwischen einem Builder und einem Relais und so weiter verwirrt, aber ich kann weiterhin erkunden und sehen, wo die Lücke ist.

Ich bin zurück. Ich kann es verstehen. Das FakeItEasyRelay wird zu den Rückstandssammlern des Geräts hinzugefügt, aber DelegateGenerator erstellt zuerst einen Delegaten.
Eine schnelle Suche hat nicht ergeben, wie der FakeItEasy-Builder früher in die Kette eingefügt wird, aber ich suche möglicherweise nicht richtig.

Unabhängig davon, wie dies ausgeht, würde ich gerne eine PR einreichen, um das Verspotten von Fake<TDelegate> wobei TDelegate ein Delegiertertyp ist.

@blairconrad als FakeItEasy User sehne ich mich nach deiner PR :)

@blairconrad Danke für Klarstellungen und für Ihre Untersuchung! Ich habe gerade noch einmal nachgesehen und festgestellt, dass FakeItEasy tatsächlich die Fälschungen für Delegierte erstellt. Wahrscheinlich habe ich in meinem vorherigen Test etwas übersehen

Zum Erstellen einer Func, habe ich es schnell versucht und festgestellt, dass das Gerät DelegateGenerator verwendet, um einen (nicht-FakeItEasy) Delegaten zu erstellen.

Ja. Wir haben genau das gleiche Problem mit Moq - AutoFixture fängt diese Anfragen ab, bevor die ResidueCollectors die Möglichkeit haben, sich einzumischen.

Ich würde vorschlagen, dieses Problem wie folgt zu beheben:

  • Methodenabfrage erweitern, um Fake<Delegate> Anfragen zu unterstützen;
  • Fügen Sie eine neue Anpassung hinzu, die der Customizations Sammlung ein Relay hinzufügt, sodass die Delegate-Anfrage _bevor_ vom AutoFixture-Kernel verarbeitet (weitergeleitet) wird. Das heißt, diese Funktion wird standardmäßig nicht aktiviert, Benutzer können sie jedoch problemlos mithilfe einer vordefinierten Anpassung aktivieren.

@blairconrad Könnten Sie außerdem bitte beschreiben, was der Vorteil des gefälschten Delegierten gegenüber dem von der AutoFixture erstellten ist? Im Moment fällt mir nur eins ein - Sie können sie mit der gefälschten Bibliothekskonfigurationssyntax konfigurieren.

Danke, @zvirja.

Ich denke, du hast recht. Der Vorteil eines gefälschten Delegaten wäre, dass er mit der gefälschten Bibliothekskonfigurationssyntax konfiguriert werden könnte.

Ich freue mich, die Methodenabfrage zu erweitern, um Fake<Delegate> , und werde eine zusätzliche Anpassung hinzufügen, genau wie Sie es sagen, aber frage mich: Ist eine, die Delegate gut genug? Was passiert, wenn der nächste gemeldete Fehlerwunsch IEnumerable oder Task oder IDictionary von FakeItEasy gefälscht wurde?

Oh, @zvirja hat um Bestätigung der Syntax für das Fälschen eines Delegaten gebeten. Es wurde jetzt mit FakeItEasy/FakeItEasy#1321 in die Dokumentation von FakeItEasy zusammengeführt, aber um es explizit zu sagen:

```c#
var fakeDelegate = A.Fake>();

is the preferred syntax for clients, although "unnatural fakes" can be used:

```c#
var fakeDelegate = new Fake<Func<int, int>>();

Letzteres ist, wie die Klasse FakeItEasyBuilder den Fake erstellen würde.

Lustige Tatsache: Das Fälschen von Delegaten wurde bis Version 1.7.4257.42 nicht unterstützt (wahrscheinlich FakeItEasy/FakeItEasy@edb4f61d0db0a84b68c7a9395f2661a58579d34a). Persönlich habe ich kein Problem damit zu sagen "Sie bekommen das nicht, es sei denn, Sie verwenden mindestens diese Version von FakeItEasy". @zvirja oder andere, halten Sie das für ein Problem? Ich muss mit den Komponententests einige Tricks anstellen, um sicherzustellen, dass wir die vorhandenen AutoFakeItEasyUnitTest-Tests nicht brechen.
Es sei denn, Sie möchten die Mindestversion von FakeItEasy für diesen Fix aktualisieren. Ich würde es wahrscheinlich nicht tun, zumal das Anfordern eines Delegierten bei diesen Versionen sowieso fehlgeschlagen wäre.

@blairconrad Vielen Dank für deine Arbeit daran!

@zvirja oder andere, halten Sie das für ein Problem?

Überhaupt nicht. Gemäß der SemVer, die wir hier verfolgen, dürfen wir die Abhängigkeitsversion innerhalb derselben Hauptversion nicht ändern. Daher würde ich sagen, dass der richtige Schritt darin besteht, eine solche Unterstützung für die FakeItEasy-Versionen hinzuzufügen, die diese Funktion unterstützen. Später möchten wir vielleicht die 1.x-Unterstützung in v5 (aus Konsistenzgründen) fallen lassen, aber das wird nur in Zukunft passieren.

Konvertieren dieses Problems in ein Feature, wie wir vereinbart haben, damit fortzufahren (und FakeItEasy unterstützt die Delegierten).

Veröffentlicht in v4.2.0! Ermöglichen:
c# fixture.Customize(new AutoFakeItEasyCustomization { GenerateDelegates = true });

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen