2009-02-13 6 views
1

Étant donné le SUT suivant, considéreriez-vous que ce test d'unité est inutile? ** edit: nous ne pouvons pas supposer que les noms correspondent, donc la réflexion ne fonctionnerait pas.Ce test d'unité est-il excessif?

** edit 2: en réalité, cette classe implémenterait une interface IMapper et il y aurait un test complet de comportement (mock) au niveau de la couche logique métier de l'application. ce test s'avère être le plus bas niveau de test qui doit être basé sur l'état. Je me demande si ce test est vraiment nécessaire parce que le code de test est presque identique au code source lui-même, et basé sur l'expérience réelle, je ne vois pas comment ce test unitaire facilite la maintenance de l'application.

//SUT 
public class Mapper 
{ 
    public void Map(DataContract from, DataObject to) 
    { 
    to.Value1 = from.Value1; 
    to.Value2 = from.Value2; 
    .... 
    to.Value100 = from.Value100; 
    } 
} 

//Unit Test 
public class MapperTest() 
{ 
    DataContract contract = new DataContract(){... } ; 
    DataObject do = new DataObject(){...}; 
    Mapper mapper = new Mapper(); 
    mapper.Map(contract, do); 
    Assert.AreEqual(do.Value1, contract.Value1); 
    ... 
    Assert.AreEqual(do.Value100, contract.Value100); 

} 

Répondre

2

Ce n'est pas excessif. Je ne suis pas sûr qu'il se concentre entièrement sur ce que vous voulez tester.

"Under the strict definition, for QA purposes, the failure of a UnitTest implicates only one unit. You know exactly where to search to find the bug."

La puissance d'un test unitaire est d'avoir un état résultant correct connu, l'accent doit être les valeurs attribuées aux DataContract. Ce sont les limites que nous voulons pousser. Pour vous assurer que toutes les valeurs possibles pour DataContract peuvent être copiées avec succès dans DataObject. DataContract doit être rempli avec des valeurs de casse.

PS. David Kemp a raison de dire que 100 tests bien conçus seraient les plus fidèles au concept des tests unitaires.

Note: Pour ce test, nous devons supposer que DataContract se remplit parfaitement lors de la construction (ce qui nécessite des tests séparés).

3

je voudrais remettre en question la construction elle-même, pas la nécessité de le tester

[réflexion serait beaucoup moins de code]

+0

Écrire le test que j'ai pu avoir à propos de la septième propriété avant que j'aurais pensé, "ce serait plus facile avec la réflexion." Rédaction du test avec réflexion aurait conduit à la conclusion évidente que l'écriture du code en utilisant la réflexion serait plus facile. – tvanfosson

+0

J'utiliserais l'émission de code plutôt que la réflexion pour faire ceci si tous les noms de propriété correspondaient. Ce serait un peu plus rapide: p –

+0

@ [Otter]: ne laissez pas le commentaire de réflexion détourner l'attention du point principal - cette classe est d'une valeur douteuse, quel que soit le test unitaire. A quoi bon assigner une centaine de champs d'une classe à une autre? pourquoi ne pas les mettre dans un dictionnaire et copier cela? ou juste faire une autre référence –

0

pas si cela a été le seul test unitaire de ce genre dans l'ensemble app. Cependant, le deuxième autre comme ça est apparu, vous me verriez froncer les sourcils et commencer à penser à la réflexion.

2

Il est préférable de tester à un niveau supérieur, c'est-à-dire la logique métier qui nécessite la création de la fonction Mapper.Map().

+0

Cela ne multiplie-t-il pas les raisons possibles de l'échec du test? J'avais l'impression que, idéalement, tous les niveaux sont testés, de sorte que l'échec puisse être repéré au bon endroit dès qu'une régression se produit. –

+0

À mon humble avis, le problème avec les tests à un niveau trop bas est qu'il rend les tests trop rigides/cassants. Si la mise en œuvre de bas niveau est modifiée, mais que les besoins de l'entreprise sont toujours satisfaits, un test de niveau inférieur tel que celui-ci pourrait échouer, alors que le test de niveau supérieur ne le serait pas. – RickL

3

Je dirais que c'est nécessaire. Cependant, il serait préférable que 100 tests unitaires distincts, chacun vérifiant une valeur. Ainsi, lorsque vous rencontrez un problème avec value65, vous pouvez exécuter les tests et constater immédiatement que value65 et value66 sont en cours de transposition. Vraiment, c'est ce genre de code simple où vous éteignez votre cerveau et oubliez que des erreurs se produisent. Avoir des tests en place signifie que vous les ramassez et non vos clients. Cependant, si vous avez une classe avec 100 propriétés toutes nommées ValueXXX, vous pourriez être mieux en utilisant un tableau ou une liste.

+0

Bien sûr, ces 100 tests seraient dans leur propre appareil de test, le mappage étant effectué dans la méthode SetUp. –

+0

Wow, vous créeriez vraiment 100 tests unitaires séparés pour tester cette fonction? Ça me semble un peu OTT. – RickL

+1

@Rick - Je me suis vite lassé d'écrire 100 tests unitaires, et j'ai trouvé une meilleure façon de résoudre le problème. –

0

Non Excesive.

Je suis d'accord le code semble étrange, mais qui a dit:

La beauté de test unitaire est qu'une fois que cela se fait est là pour toujours, donc si quelqu'un pour une raison quelconque décide de changer cette mise en œuvre quelque chose de plus « intelligent » encore le test devrait passer, donc pas un gros problème. Personnellement, j'aurais probablement un script Perl pour générer le code car je m'ennuierais à remplacer les chiffres pour chaque assertion, et je ferais probablement des erreurs en cours de route, et le script Perl (ou n'importe quel script) serait plus rapide pour moi.

+0

Que faire si dans la plupart des cas toutes les valeurs seront des types de base? Je pense qu'il est raisonnable de supposer que personne ne trouvera quelque chose de mieux que d'utiliser l'opérateur égal sur les types de base, alors maintenant la seule chose à s'inquiéter est d'ajouter/supprimer des champs de valeur. –