J'ai une Foo classe qui utilise une autre barre de classe pour faire des choses. J'essaie de faire du développement piloté par les tests, et donc j'écris des tests unitaires pour Foo pour m'assurer qu'il appelle les méthodes appropriées sur Bar, et pour cela j'utilise l'injection de dépendances et le moqueur Bar (en utilisant Rhino Mocks).construction/d'initialisation de l'objet de test Unité
E.g. (En C#):
class Foo
{
private IBar bar= null;
public Foo(IBar bar)
{
this.bar= bar;
}
public void DoSomething()
{
bar.DoIt();
}
}
class FooTests
{
...
void DoSomethingCallsBarsDoItMethod()
{
IBar mockBar= MockRepository.GenerateMock<IBar>();
mockBar.Expect(b=>b.DoIt());
Foo foo= new Foo(mockBar);
foo.DoSomething();
mockBar.VerifyAllExpectations();
}
}
Tout cela semble bien, mais je veux vraiment Bar à configurer avec un paramètre particulier, et allait avoir ce paramètre passé via le constructeur de Foo. E.g. (En C#):
public Foo(int x)
{
this.bar = new Bar(x);
}
Je ne sais pas quelle est la meilleure façon de changer cela pour être plus facilement testables. Une des options que je peux penser consiste à déplacer l'initialisation de Bar hors de son constructeur, par ex. J'ai l'impression que cela rend Bar plus difficile à utiliser cependant. Je soupçonne qu'il pourrait y avoir une sorte de solution qui impliquerait l'utilisation d'un conteneur IoC configuré pour injecter Foo avec une imitation IBar et fournirait également un accès à la maquette créée pour la validation des attentes, mais je pense que cela rendrait Foo inutilement complexe . Je suis seulement en utilisant l'injection de dépendance pour me permettre de se moquer des dépendances pour les tests, et donc je ne suis pas en utilisant des conteneurs IoC actuellement, juste construire des dépendances dans un appel constructeur enchaîné des constructeurs par défaut (même si je sais que cela crée un code plus non testé) par exemple
public Foo() :
this(new Bar())
{
}
Quelqu'un peut-il recommander la meilleure façon de tester la construction/initialisation d'objet dépendant?
Foo ne se soucie pas de x, sauf que Bar doit être initialisé avec lui. J'ai édité ma question pour clarifier ceci. Merci. – Ergwun
@Ergwun: Si Foo ne se soucie pas de x, il suffit de créer Bar avec x et de l'injecter dans Foo. Si x ne peut pas être connu avant l'exécution, utilisez une Usine abstraite pour créer IBar dans Foo - voir le dernier lien de ma réponse. –
Après avoir essayé pendant un certain temps, j'ai trouvé que l'utilisation de la fabrique de motifs abstraits était extrêmement utile pour ce genre de problème. Merci! – Ergwun