Procédé Fixture.CreateAnonymous tue processus de lanceur de test avec une erreur (AutoFixture) lors de l'utilisation AutoMoq pour créer un contrôleur

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

Question

Je suis en train d'utiliser le AutoMoqCustomization avec AutoFixture pour créer un contrôleur ASP.NET MVC2 dans un test unitaire via la méthode Fixture.CreateAnonymous. Je l'ai essayé dans les deux xUnit sous TestDriven.NET, l'interface graphique de test xUnit et MSTest et tous ont le même résultat: un échec massif du processus en cours d'exécution du test. Sous Windows 7 x64 si cette question.

Pour reproduire, il suffit de créer un nouveau projet ASP.NET MVC2, ajoutez les références à AutoFixture, AutoMoq et Moq (3.1, selon la source AutoMoq) et essayer le ci-dessous (repro VS2010 MVC2 lien de projet ci-dessous):

[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>();
}

Dans MSTest l'erreur se lit comme suit:

  

Le temps d'exécution a rencontré une erreur fatale. L'adresse de l'erreur était 0x6465f370, le fil 0x2684. Le code d'erreur est 0xc0000005. Cette erreur peut être un bogue dans le CLR ou dans les parties dangereuses ou non vérifiables du code utilisateur. Les sources courantes de ce bogue comprennent les erreurs utilisateur de marshaling pour COM-Interop ou PInvoke, qui peut corrompre la pile.

AfWithMvc repro projet (de SkyDrive)

Était-ce utile?

La solution

Solution proposée

Pour commencer une solution possible, cela devrait arrêter le plantage:

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>();

Explication

Et maintenant l'explication:

Cette erreur de test est causée par la AutoFixture AutoProperties fonction en essayant d'attribuer une valeur à HomeController.ViewData.ModelMetaData. La classe ModelMetaData a ce constructeur:

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

Le coupable est le paramètre modelAccessor ici. Pour combler cette AutoFixture de propriété (plutôt sans réfléchir) reflète sur le type et trouve ce seul constructeur:

public Func(object @object, IntPtr method)

Creuser plus loin, le premier constructeur AutoFixture IntPtr peut satisfaire est celui-ci:

public unsafe IntPtr(int value)

Par défaut, cas Int32 sont créés par une séquence montante déterministe , donc value dans ce cas sera probablement 1 ou 2 ou un petit nombre entier similaire. En d'autres termes, nous avons maintenant un très invalide pointeur dangereux sur nos mains, ce qui rend le crash du processus.

Maintenant, dans des circonstances normales, nous devrions être en mesure de résoudre ce problème en enregistrant un Func<object> avec l'appareil et tout devrait être dandy:

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

Cependant, j'ai essayé avec votre repro et bien que le processus ne se bloque plus de la même manière, les pistes d'essai pour un temps très long et, enfin, se brise avec un OutOfMemoryException.

Je ne sais pas ce que ASP.NET MVC fait avec Func<object>, mais apparemment il utilise assez heaviliy.

Les restes de question de savoir si ce bogue dans AutoFixture?

Je crois que ce n'est pas. Bien qu'il soit nettement moins qu'idéal, AutoFixture ne funcs pas traiter ou actions différemment que les autres types, ce qui est la raison pour laquelle nous voyons ce comportement.

Ce comportement particulier pourrait être résolu en ajoutant un soutien spécifique pour Func<TResult>, mais rester cohérent, il devrait également avoir un soutien pour Func<T, TResult>, Func<T1, T2, TResult>, etc. AFAIR dans .NET 4 il y a beaucoup de ces types de délégués (également d'action, etc.), de sorte que signifierait l'ajout du support pour une multitude de types.

Mais que dire de tous les autres types qui prennent un IntPtr dans leur constructeur? AutoFixture ne peut peut-être connaître tous, donc cela ne semble pas comme une direction viable.

Cependant, ce que peut garde qui l'empêche de tenter pour créer des instances IntPtr en premier lieu . Ce sera très probablement ajouté avant le 2.0 RTW.

Merci d'avoir signalé ce.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top