en double possible:
Using IoC for Unit TestingCombinant tests unitaires (se moquant) et un cadre d'injection Dependecy
Je pense que j'ai un problème à comprendre les tests unitaires de manière et/ou injection de dépendance sont travail. J'utilise NUnit et Rhino Mocks pour les tests unitaires et Ninject en tant que Framework d'Incidences de Dépendances. En général, je pense que ces deux-là seraient parfaits - mais d'une certaine manière, il semble que cela devienne de plus en plus compliqué et difficile à comprendre.
(Je vais essayer de donner un bon exemple, pour le garder propre et facile, c'est à propos de moi, faire du vélo).
1.) Sans DI/Tests unitaires:
sans connaître de DI et de tests unitaires, mon code aurait regardé comme ça - et je serais heureux:
public class Person
{
public void Travel()
{
Bike bike = new Bike();
bike.Ride();
}
}
public class Bike
{
public void Ride()
{
Console.WriteLine("Riding a Bike");
}
}
monter ma vélo, je voudrais juste besoin: new Person().Travel();
2.) Avec DI:
Je ne veux pas que le couplage serré, donc je besoin d'une interface et un NinjectModule! J'aurais des frais généraux, mais ça ira, tant que le code est facile à lire et à comprendre. Je vais juste passer le code de la classe Person modifiée, la classe de vélo est inchangé:
public class Person
{
IKernel kernel = new StandardKernel(new TransportationModule());
public void Travel()
{
ITransportation transportation = kernel.Get<ITransportation>();
transportation.Ride();
}
}
je pouvais encore monter mon vélo avec juste: new Person().Travel();
3.) Compte tenu de tests unitaires (sans DI):
Pour être en mesure de vérifier si la méthode Ride est appelée correctement, j'ai besoin d'un Mock. Pour autant que je sache, il existe généralement deux façons d'injecter une interface: Constructor Injection et Setter Injection. Je choisis Injection Constructor pour mon exemple:
public class Person
{
ITransportation transportation;
public person(ITransportation transportation)
{
this.transportation = transportation;
}
public void Travel()
{
transportation.Ride();
}
}
Cette fois-ci, je NEET passer le vélo: new Person(new Bike()).Travel();
4.) Avec DI et la préparation des tests unitaires
La classe 3. Considérant Unit-Testing (sans DI) ferait le travail sans modification, mais je devrais appeler new Person(kernel.Get<ITransportation>());
. Grâce à cela, j'ai l'impression que je perds le bénéfice de DI - la classe Personne pourrait appeler Voyage sans aucun couplage et aucun besoin de savoir quel genre de classe le transport est. En outre, je pense que cette forme manque beaucoup de la lisibilité de l'exemple 2.
Est-ce ainsi que c'est fait? Ou y a-t-il d'autres façons plus élégantes de réaliser l'injection de dépendances et la possibilité d'effectuer des tests unitaires (et de simuler)?
(En regardant en arrière, il semble que l'exemple est vraiment mauvais - tout le monde devrait savoir quel type d'appareil de transport il monte en ce moment ...
Je pense que vous pourriez être confus au sujet des définitions de l'injection de dépendance (DI) et de l'inversion de contrôle (IoC). Vous êtes le troisième chiffre * met * en œuvre DI (vous avez déplacé la dépendance vers le constructeur), votre deuxième chiffre utilise le conteneur IoC (Ninject) pour résoudre les dépendances. –
zapthedingbat a raison. Vous faites DI dans le troisième exemple, mais n'utilisez pas le conteneur DI, ce qui est bien. Le conteneur DI est facultatif lorsque vous faites DI. – Steven
Exemple "2" n'utilise pas DI, mais un "Service Locator" ... –