1

Mon équipe est en train de développer un système dans lequel nous utilisons Unity comme conteneur IoC; et pour fournir des ISessions de NHibernate (unités de travail) sur chaque requête HTTP, nous utilisons ChildContainer feature de Unity pour créer un conteneur enfant pour chaque requête et y coller l'ISession.Système de test où des conteneurs IoC de niveau application et de niveau requête existent

Nous sommes arrivés à cette approche après trying others (including defining per-request lifetimes in the container, but there are issues there) et essayons maintenant de décider d'une stratégie de test unitaire. À l'heure actuelle, le conteneur au niveau de l'application lui-même réside dans HttpApplication et le conteneur Request se trouve dans HttpContext.Current. Evidemment, aucun n'existe pendant les tests. La douleur augmente lorsque nous avons décidé d'utiliser Service Location à partir de notre couche Domain, pour "paresseusement" résoudre les dépendances du conteneur. Alors maintenant, nous avons plus de composants qui veulent parler au conteneur.

Nous utilisons également MSTest, qui presents some concurrency dilemmas également pendant le test. Nous nous demandons donc ce que font les gens brillants de la communauté SO pour s'attaquer à cette situation difficile? Comment configurer une application qui, pendant le "vrai" runtime, repose sur des objets HTTP pour contenir les conteneurs, mais pendant le test a la flexibilité de construire et de démonter les conteneurs de manière cohérente, et avoir les bits ServiceLocation arriver à ces conteneurs précis.

J'espère que la question est claire, merci!


Merci pour les réponses. Je suis d'accord que l'utilisation de Service Location n'est pas l'approche optimale - mais cela semble nécessaire pour cette situation. Le scénario est que nous avons besoin de nos entités pour résoudre les dépendances, à la demande, uniquement si nécessaire - pour la validation des règles métier. Forcer nos entités, lorsqu'elles sont matérialisées par NHibernate, à subir une injection de constructeur, ne semble pas appropriée, au minimum pour des raisons de performance.

Nous considérons une solution où les conteneurs sont stockés dans le HttpApplication/HttpContext en temps réel, et dans les champs static/ThreadStatic pendant le test. StructureMap has a similar approach baked-in. Des pensées sur ce genre de solution? Merci!

De plus, il ne s'agit pas nécessairement de tests d'intégration (bien que cela puisse également jouer dans ce sens). Par exemple, nous souhaitons tester de manière unitaire le comportement d'une entité particulière au cours de laquelle ce scénario se déroulera.

Je suis définitivement ouvert aux abstractions d'objets Http - je les ai utilisés et aimés dans MVC; comment peut-on les faire sortir de MVC?

+0

Si vous testez vos classes individuelles, j'appellerais cela "test unitaire". Mais si vous essayez de vous assurer que toutes vos classes interagissent de manière appropriée avec le conteneur Unity, alors je l'appellerais "test d'intégration". Cela pourrait vous aider à trouver de meilleures réponses, peut-être comme http://weblogs.asp.net/jdanforth/archive/2009/01/30/integration-testing-wcf-services-with-unity.aspx – John

Répondre

0

DI Conteneurs should not be necessary during unit testing. Plutôt, un conteneur DI est utilisé au moment du démarrage de l'application pour résoudre le graphe de dépendance de l'application, et , puis se met à l'écart. Cependant, il semble que vous ayez appliqué le code Service Locator anti-pattern, et vous ressentez maintenant la douleur de cela. Malheureusement, il n'y a pas de solution facile.

Vous ne pouvez évidemment pas compter sur le vrai contexte HTTP lors des tests unitaires, car il ne sera pas disponible dans cet environnement, vous devrez donc les cacher derrière les interfaces. Si vous utilisez.NET 3.5 SP1, vous pourriez être en mesure d'utiliser les abstractions introduites dans System.Web.Abstractions, mais sinon, vous pouvez en extraire vous-même.

Une fois que vous avez introduit ces Seams dans votre système, vous pouvez utiliser l'injection de dépendance appropriée (de préférence Constructor d'injection) pour les injecter dans vos catégories de consommateurs.

Dans tous les cas, suivant Développement axé sur les essais peut très efficacement empêcher d'introduire ce type de couplage étanche en premier lieu.

+0

OK, après nous être réunis a décidé qu'éliminer l'utilisation de ServiceLocation était probablement la voie à suivre. Nous avons été en mesure de l'exciser à partir de la couche de domaine en mettant le fardeau sur la couche d'application (Service WCF) pour résoudre les dépendances liées aux règles et les transmettre dans les Entités selon les besoins. Merci beaucoup pour les liens (super blog) et répondez. – Bobby

+0

FWIW, voir cette réponse sur l'activation de DI dans WCF: http://stackoverflow.com/questions/2042609/injecting-data-to-a-wcf-service/2042858#2042858 –

Questions connexes