Ich definierte einen Typ mit ein paar benutzerdefinierten Generatoren, damit FsCheck benutzerdefinierte Instanzen von ein paar Typen generieren. Aber für einen der komplexen Typen möchte ich zuerst die Standard-FsCheck-Generierung verwenden und dann das Ergebnis anpassen. Hier ist eine (vereinfachte) Code:Aufruf Standard-FsCheck-Generator von einem benutzerdefinierten Generator des gleichen Typs
type CustomGenerators =
static member FirstCustomType() = /* function that returns FirstCustomType */
static member SecondCustomType() =
Arb.generate<SecondCustomType>
|> Gen.map (fun x -> /* adjust some data in the generated instance */)
|> Arb.fromGen
Das Problem ist, dass, wenn SecondCustomType() statische Methode nennt es Arb.generate ruft sofort SecondCustomType() verursacht eine endlose Rekursion. Ich verstehe, dass Arb.generate benutzerdefinierte Generatoren respektieren muss, deshalb ruft es statische SecondCustomType() auf, aber ich muss die standardmäßige (nicht angepasste) Arb.generate-Implementierung für SecondCustomType aufrufen. Ich kann die Implementierung nicht von einem anderen Typ aufrufen, da mein benutzerdefinierter Generator einen benutzerdefinierten Generator für FirstCustomType verwendet. Daher muss die SecondCustomType-Standardimplementierung alle benutzerdefinierten Generatoren kennen, die im Typ CustomGenerators definiert sind. Dies ist eine Art schlechter Kreis, für den ich noch keine saubere Lösung gefunden habe (nur Workaround).
Ich würde vorschlagen, "SecondCustomType" in einem trivialen Wrapper nur für den Test, sagen "SecondCustomTypeTestWrapper", definieren Sie den benutzerdefinierten Generator für diesen Wrapper, nicht für "SecondCustomType" selbst, und Ihr Test nehmen Sie den Wrapper als Parameter. –
Ja, das ist, was ich bereits getan habe, aber ich frage mich, ob es einen besseren Weg ohne zusätzlichen Typ Wrapper gibt. –
Anstatt sofort Arbitratoren in statischen Klassen zu definieren, konnten Sie nicht einige normale F # -Funktionen definieren, die gen-Werte zurückgeben, und sie dann so zusammenstellen, wie Sie sie benötigen? Das ist, was ich normalerweise tue, aber dann verwende ich nie statische Convention-basierte Klassen ... –