Fixture.CreateAnonymous Verfahren abtötet Test runner Prozess mit einem Fehler (AutoFixture), wenn AutoMoq über einen Regler zu schaffen,

StackOverflow https://stackoverflow.com/questions/3514102

Frage

Ich versuche, die AutoMoqCustomization mit AutoFixture zu verwenden, um einen ASP.NET MVC2-Controller in einem Unit-Test über die Fixture.CreateAnonymous Methode zu erstellen. Ich habe in beiden xUnit unter TestDriven.NET versucht, die xUnit Test GUI und in MSTest und alle haben das gleiche Ergebnis: ein massives Versagen des Prozesses der Durchführung des Tests. Unter Windows 7 x64 wenn diese Fragen.

zu reproduzieren, erstellen Sie einfach ein neues Projekt ASP.NET MVC2, fügen Sie die Verweise auf AutoFixture, AutoMoq und Moq (3.1, gemäß der AutoMoq Quelle) und versuchen, unter den (Repro VS2010 MVC2 Projekt Link unten):

[TestMethod]
public void Index()
{
 var fixture = new Fixture().Customize(new AutoMoqCustomization());
    // here's where the error in the test host occurs:
 HomeController controller = fixture.CreateAnonymous<HomeController>();
}

In MSTest der Fehler lautet:

  

Die Laufzeit hat einen fatalen Fehler aufgetreten. Die Adresse des Fehlers war 0x6465f370, auf Faden 0x2684. Der Fehlercode ist 0xc0000005. Dieser Fehler kann ein Fehler in den CLR oder in den unsicheren oder nicht eich Teilen des Benutzercodes sein. Häufige Quellen dieser Fehler sind Benutzer Serialisieren Fehler für COM-Interop oder PInvoke, die möglicherweise beschädigt den Stapel.

AfWithMvc Repro-Projekt (von SkyDrive)

War es hilfreich?

Lösung

Lösungsvorschlag

mit einer möglichen Lösung zu starten, soll dies den Absturz stoppen:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
// This should fix the problem for all Controllers
fixture.Customize<ViewDataDictionary>(c =>
    c.Without(x => x.ModelMetadata));

HomeController controller = fixture.CreateAnonymous<HomeController>();

Erklärung

Und nun die Erklärung:

Dieser Test Fehler wird durch AutoFixture verursacht wurden AutoProperties Funktion versucht, einen Wert zu HomeController.ViewData.ModelMetaData zuzuweisen. Die ModelMetaData Klasse hat diesen Konstruktor:

public ModelMetadata(
    ModelMetadataProvider provider,
    Type containerType,
    Func<object> modelAccessor,
    Type modelType,
    string propertyName)

Der Täter ist hier der modelAccessor Parameter. Um diese Eigenschaft AutoFixture zu füllen (und nicht gedankenlos) reflektiert über die Art und findet diesen einzelnen Konstruktor:

public Func(object @object, IntPtr method)

Graben weiter, der erste IntPtr Konstruktor AutoFixture erfüllen kann, ist diese:

public unsafe IntPtr(int value)

Standardmäßig Int32 Instanzen werden durch eine deterministische Sequenz steigende erstellt , so value in diesem Fall wahrscheinlich 1 oder 2 oder eine ähnliche kleine ganze Zahl sein. Mit anderen Worten, wir haben jetzt ein sehr ungültig unsichere Zeiger auf unseren Händen, und dies den Prozess Absturz macht.

Nun, unter normalen Umständen sollten wir in der Lage sein, dies zu beheben, indem ein Func<object> mit dem Fixture Registrierung und alles soll sein Dandy:

fixture.Register<Func<object>>(() => () => new object());

Allerdings habe ich versucht, dies mit Ihrem Repro und obwohl der Prozess nicht mehr in der gleichen Art und Weise abstürzt, wird die Testläufe für eine sehr lange Zeit, und schließlich stürzen mit einem OutOfMemoryException.

Ich weiß nicht, was ASP.NET MVC mit Func<object> tut, aber anscheinend es verwendet es ganz heaviliy.

Die Frage bleibt, ob es sich um einen Fehler in AutoFixture?

Ich glaube, dass es nicht ist. Während es auf jeden Fall weniger als ideal ist, AutoFixture nicht behandeln funcs oder Aktionen anders als andere Arten, weshalb wir dieses Verhalten zu sehen.

Dieses besondere Verhalten möglicherweise durch das Hinzufügen spezifische Unterstützung für Func<TResult> angegangen werden könnte, sondern bleibt im Einklang es auch Unterstützung für Func<T, TResult> haben sollte, Func<T1, T2, TResult> usw. AFAIR in .NET 4 gibt es viel von diese Delegattypen (auch Aktion, etc.), so dass das Hinzufügen von Unterstützung für eine ganze Reihe von Arten bedeuten würde.

Aber was ist dann mit allen anderen Typen, die einen IntPtr in ihrem Konstruktor nehmen? AutoFixture kann möglicherweise nicht wissen, über sie alle, so dass diese nicht wie eine tragfähige Richtung scheint.

Doch was es könnte haben, ist ein guard, dass es verhindert, dass von dem Versuch IntPtr Instanzen in erster Linie zu erstellen. Dies wird höchstwahrscheinlich vor dem 2.0 RTW hinzugefügt werden.

Danke für die Meldung.

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