0
votes

Comment affirmer le nombre d'affirmations (ou une autre façon d'appliquer que tous les membres ont été testés dans une affirmation)?

Dans un certain test de l'unité pour ma classe, je tiens à affirmer qu'une affirmation a été écrite pour tous les champs membres. C'est-à-dire, donné xxx

je veux faire quelque chose comme xxx

bien sûr, compter le nombre d'affirmations ne garantit pas qu'ils ne garantissent pas avait quelque chose à voir avec chaque champ ayant une affirmation. Mais, j'essaie simplement d'écrire un test qui échoue si un développeur ajoute un champ à FOO et oublie de mettre à jour ce test.

  • approche naïvest: La chose la plus simple que je puisse penser est d'utiliser la réflexion pour affirmer le nombre de champs foo a, par exemple Assertequals (3, foo.getDeclaredfields (). Compte ()) . Mais, je peux facilement voir un programmeur qui heurte le nombre sans ajouter une affirmation.

  • toujours une approche naïf, mais acceptable: Je pense que si je peux au moins compter le nombre d'affirmations, il guiderait suffisamment les programmeurs vers le besoin envisagé .

  • APPROCHES plus précises: Bien sûr, il semble bien sûr que la meilleure approche consiste à garder réellement une table dont les champs sont apparus dans l'affirmation ( par exemple, par exemple via un wrapper Méthode comme AssertequalswithCounters ), mais en réalité ma situation est un peu plus compliquée. Par exemple, mon modèle est en fait une classe générée ( @automatter ) et je vais utiliser des getters des deux côtés de l'affirmation, il sera donc difficile de déduire vraiment quel champ a été "touché "Par une affirmation. C'est pourquoi il suffit de compter des affirmations et de rester agnostique à des types et de comptes réels, serait le plus facile pour moi.


3 commentaires

Une approche beaucoup plus simple est (1) utilise Lombok pour que votre classe ait une totring générée, vous savez donc que toutes les variables membres. (2) comparer simplement les résultats de Tostring.


@Zag mais s'appuyant sur la production de tostring () est extrêmement mauvaise. Et que si cette classe a déjà une totring () ou d'autres?


Utilisez openpojo .


3 Réponses :


2
votes

Je pense que vous devrez peut-être utiliser PowerMockito comme Mockito ne supporte pas les méthodes statiques moqueuses .

Je n'ai pas testé le code ci-dessous - mais mon idée serait de faire Ce qui suit: xxx


1 commentaires

Une bonne idée, mais honnêtement, plutôt une solution de contournement sale. Tout d'abord, cette moqueur statique peut rapidement conduire à toutes sortes de problèmes. Par exemple, il y a un tas de règles que vous devez suivre, comme vous avez besoin d'une annotation de la préparation. Qui manque de votre exemple. Je me demande donc si votre code fonctionne vraiment. Je me demande également si ces espionnés d'affirmation ... faisons vraiment un chèque d'affirmation. Avez-vous vérifié qu'ils feu lorsque l'affirmation ne tient pas?



3
votes

Mais j'essaie simplement d'écrire un test qui échoue si un développeur ajoute un champ to foo et oublie de mettre à jour ce test. P>

Ma société utilise un cadre de mappage pour mapser les haricots de la DB, les champs sont un à un avec la base de données, à un haricot de modèle que nous retournons au client que nous pouvons modifier au besoin. Je crois que c'est un cas d'utilisation courante et essentiellement ce que vous essayez d'obtenir. Vous devriez être moins préoccupé par le test des modifications apportées à FOO CODE>, et plus préoccupée par rien ne rompre avec le mappage de FOO code> à bar code>. strong> p> xxx pré>

alors nous avons un test de provénement qui utilise isequaltocomparingfieldbyfieldrecursivement code> pour comparer les deux haricots. P>

private Bean bean = new Bean();
private Bean beanDb = new BeanDb();
private BeanProvider provider = new BeanProvider();

@Before
public void setup(){
 bean.setA(1);
 bean.setB(2);

 beanDb.setA(1);
 beanDb.setB(2);
}

@Test
public void prepareForDatabase(){
    BeanDb db = provider.prepareForDatabase(bean);

    assertThat(beanDb).isEqualToComparingFieldByFieldRecursively(db);
}

@Test
public void populateFromDatabase(){
    Bean model = provider.populateFromDatabase(beanDb);

    assertThat(model).isEqualToComparingFieldByFieldRecursively(bean);
}


2 commentaires

J'aime beaucoup votre réponse, alors j'ai aussi ajouté ma variation de celle-ci ;-)


HM, l'ajout de nouveaux champs était l'une des raisons principales que je voulais une capture automatique dans mon cas ... mais merci, je garde des mappeurs à l'esprit depuis votre suggestion.



1
votes

Je pense que la réponse à xxx pré>

est: vous faites pas fort> fais cela. Ce test est proche de l'inutile. P>

S'il n'y a que 3 champs, vous pouvez voir strong> avec vos yeux que vous vérifiez ces trois champs. Vous pensez probablement à 15 champs de cette classe, mais ensuite: p> xxx pré>

... Assertables (modèle.o, externeModel.geto (). Tostring ()); P>

assertNumberOfAssertionsInThisTest(15); 


2 commentaires

Ah désolé. Voir, où j'avais construit pour faire quelque chose comme ceci: Assertequals (3, mybaSeclass.class.getdeclaredfieldfields (). Longueur); . Donc, si des champs sont ajoutés à la classe de base, l'affirmation serait échouer, allonant au programmeur que quelque chose doit être fait. Mais je suis d'accord que cela n'est guère le meilleur design.


@Andrewcheong comme dit: Pour 3 champs, vous pouvez voir cela. Lorsque vous avez 15 champs, vous pouvez obtenir le nombre de points, mais ne testez toujours que 14 champs facilement.