2017-06-05 1 views
2

Nous utilisons UnityAutoMoq pour se moquer de la plupart de nos interfaces dans nos tests unitaires, mais j'ai récemment rencontré une situation où nous voulions utiliser un framework de test pour simuler plus complètement le comportement réel (appelez-le test d'intégration si cela vous aide à accepter ce que je fais).Enregistrer des interfaces génériques avec UnityAutoMoqContainer

Je m'attendais à ce que UnityAutoMoq me laisse enregistrer des mappages concrets au lieu de permettre à UnityAutoMoqContainer de différer le fait de se moquer de l'interface. Cela est vrai pour tout ce que j'ai essayé, sauf pour les interfaces génériques. Si vous êtes visuel comme moi, voici un extrait de ce que je suis en train:

public static void Register(IUnityContainer container) 
{ 
    ... 
    container.RegisterType(typeof(IService<>), typeof(TestFrameworkService<>), 
     new HierarchicalLifetimeManager(), new InjectionFactory(Create)); 
    ... 
} 

private static object Create(IUnityContainer container, Type type, string name) 
{ 
    var T = type.GetGenericArguments().Single(); 
    return new TestFrameworkService<T>();// For simplicity, pretend this works 
} 

Comme vous pouvez le voir ci-dessus, je me inscris l'interface générique pour un béton générique, en fonction lors de l'injection puis usine pour le résoudre en utilisant le type entrant (l'implémentation réelle a été omise pour plus de simplicité). Cela fonctionne avec un UnityContainer normal, renvoyant le béton attendu. Le UnityAutoMoqContainer renvoie à la place un faux, en contournant complètement l'usine d'injection.

Est-ce que quelqu'un a essayé quelque chose comme ce que j'essaie d'accomplir? Des idées?

Répondre

0

J'ai trouvé que le problème réside dans la BuilderStrategy sous-jacente. Voici un extrait de UnityAutoMoqBuilderStrategy.

public override void PreBuildUp(IBuilderContext context) 
{ 
    var type = context.OriginalBuildKey.Type; 

    if (autoMoqContainer.Registrations.Any(r => r.RegisteredType == type)) 
      return; 

    if (type.IsInterface || type.IsAbstract) 
    { 
     context.Existing = GetOrCreateMock(type); 
     context.BuildComplete = true; 
    } 
} 

La ligne de fond est que la stratégie du générateur voit que l'interface n'est pas enregistrée et intercepte sa création. C'est parce que les définitions de types génériques ne sont pas égales aux types génériques eux-mêmes. J'ai regardé dans AutoMoq, qui a été mis à jour beaucoup plus récemment, mais il souffre de la même limitation d'interception qui empêche l'usine d'injection de se déclencher.

Pour référence, voici les bibliothèques automocking que je fait des recherches:

Si quelqu'un a une recommandation, alors s'il vous plaît laissez-moi savoir, sinon Je considérerai ceci comme la réponse.