Deux Exemples Fréquents de Couplage 테스트/구현

8850 단어 javatestingtddfrench
Supposons que vous souhaitez tester la classe User suivante(très simpliste pour l'exemple):

public class User {
    private String firstname;
    private String lastname;

    public User(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String displayName() {
        return firstname + " " + lastname;
    }
}


특정 개발자의 의견:

@Test
void displayName() {
    var firstname = "John";
    var lastname = "Doe";
    var user = new User(firstname, lastname);

    assertEquals(firstname + " " + lastname, user.displayName(), "The display name should contain the firstname and the lastname.");
}


plutôt que:

@Test
void displayName() {
    var user = new User("John", "Doe");

    assertEquals("John Doe", user.displayName(), "The display name should contain the firstname and the lastname.");
}


La logique de leur raisonnement est de vouloir supprimer la duplication des constantes représentant le nom et le prénom dans le test. Parce que la duplication, c'est force BAD.

Au-delà du fait que le second test est plus court et plus simple à lire, éliminer cette duplication en introduit une autre qui est bien plus dangereuse.

Sauriez-vous dire laquelle ?

Il s'agit du code firstname + " " + lastname 프레젠트 댄 르 프리미어 테스트. Et ce que l'on a dupliqué ici est l'algorithme utilisé par la classe User pour générer le nom à afficher.

En faisant cela, on introduit un couplage entre notre test et son implémentation. Et c'est une은 éviter를 선택했습니다.

quelle 이유를 따르십시오 ? Parce plus un test est indépendant de l'implémentation du code testé, meilleur il est: Imaginez que l'algorithme change côté production, voilà qu'on doive également le transposer dans les tests.

Traitez le code de production comme une boîte noire pour éviter de construire des test fractures.

Bien sûr, ce n'est parfois pas possible(j'en parlerais peut-être une autre fois) mais on doit s'évertuer à suivre cette règle: cela rendra nos 테스트 beaucoup moins 깨지기 쉬운.

En résumé, ne copyez pas l'algorithme à tester dans vos tests !

I y autre forme de duplication plus subtile mais que j'ai souvent vue même chez des développeurs expérimentés. 고려 대상 통합 시험:

@Test
void findUser() {
    var expectedUser = new User(1, "John", "Doe");
    var response = restTemplate.getForEntity("/users/1", User.class);
    JSONAssert.assertEquals(expected, response.getBody(), false);
}


J'ai éliminé toute la tuyauterie pour nous concentrer sur la partie utile du test: on use Spring Boot mais ça pourrait être autre selected.

Quel est le problème ici ?

Eh bien, on use la classe User dans notre test d'intégration et cette classe vient de notre code de production.

Pareil que pour précédemment, on a couplé notre test avec le code de production.

La justification est souvent de dire qu'il est plus simple de réutiliser la classe User plutôt que d'écrire notre test indépendamment de celle-ci.

가정 que l'on renomme des propriétés dans la classe User dans le cadre d'un refactoring: ce test passera toujours et ne le détectera pas.

Cela veut dire que notre API nespectera plus son contrat et ce sont les clients de cette API qui vont être mécontents.

Pour les tests d'intégration de ce type, n'utilisez pas de code côté 생산. Voici un meilleur test dans ce contexte:

@Test
void findUser() {
    String expectedUser = "{id:1, firstname:\"John\", lastname:\"Doe\"}";
    var response = restTemplate.getForEntity("/users/1", String.class);
    JSONAssert.assertEquals(expected, response.getBody(), false);
}


La solution est simplement de considérer la sortie JSON comme une String plutôt qu'un User.

Certes, cela n'a pas l'air joli mais pareil qu'avant, votre test sera beaucoup plus robuste en capturant les modifications qui changent le contrat de vos API.

좋은 웹페이지 즐겨찾기