Lors des tests, une méthode d'aide peut parfois être utile pour des tâches répétées, par exemple dans la configuration de test.
Exemple concret: Nous avons certains tests contre notre interface de repos en utilisant RestTemplate
de Spring. Pour faciliter les choses, les requêtes sont envoyées à l'aide d'une méthode d'assistance (appelons-la méthode A()
pour l'instant), qui renvoie les objets de la réponse.
Cette méthode d'assistance A()
semble polluer la classe de test, car c'est une méthode qui n'est pas en fait un test lui-même. Le fait d'avoir plusieurs méthodes d'assistance dans une classe de test a un effet négatif sur la vue d'ensemble.
Est-il acceptable de créer une deuxième classe à côté de la classe de test, qui contient toutes les méthodes d'assistance? Quelles seraient les difficultés à le faire? Ou existe-t-il d'autres moyens de garder un bon aperçu de la classe de test?
MyTestClass
-> contenant uniquement des méthodes qui sont un test actuallMyTestClassUtil
-> contenant toutes les méthodes d'assistance utilisées par MyTestClass
Est-il acceptable de créer une deuxième classe à côté de la classe de test, qui contient toutes les méthodes d'assistance?
Pas avec toutes les méthodes d'assistance, mais avec les méthodes d'assistance qui sont utilisées dans plusieurs classes de test.
Concevez vos tests de la même manière que vous implémentez des classes affaires!
Le code refactorisé est dupliqué au sein d'une classe dans une méthode locale. Si la méthode est utilisée dans différentes classes de test, déplacez-la dans une classe d'assistance de test différente utilisée par différents tests.
Donc ma classe OrderTests
a une méthode locale assertEqual(String message, IOrder expected, IOrder actual)
et mon assistant TestDataFactory
a une méthode statique createTestOrder()
qui est utilisée dans OrderTests
, PriceCalculationTests
, PaymentTests
, DeliveryTests
.
Un test peut utiliser une ou plusieurs des méthodes d'usine standard et le modifier selon les besoins. Exemple:
DeliveryTests.executeOrderWithNoDeliveryAdressShouldThrow() {
// a valid standard order with one article, user, deliveryadress, ...
Order sut = TestDataFactory.createTestOrder();
sut.setDeliveryAdress(null); // implements "WithNoDeliveryAdress"
try {
sut.execute(); // this should throw
Assert.fail(); // this should never be reached because of exception.
} catch(OrderNotCompleteException) {
}
}
Selon Michael C. Feathers dans Travailler efficacement avec le code hérité Vous pouvez créer ce qu'il a appelé une couture d'objet; Une classe implémentant l'interface que vous testez ou héritant de la classe que vous testez. dans ce cas, vous ne contaminez pas votre code d'origine avec des tests unitaires.