Cet article est le 17e jour du Calendrier de l'Avent Android 2 2016 - Qiita.
Aujourd'hui, comme l'un des modèles utiles pour maintenir le code de test, Je voudrais vous présenter le ** modèle Test Data Builder **.
Pendant le développement réel
Vous écrirez souvent du code de test pour les classes qui utilisent des modèles (tels que des objets de valeur).
Cette fois, en supposant un tel cas, l'objet de valeur est ʻUser, et la classe qui l'utilise est ʻUserRepository
.
Continuons avec l'histoire comme exemple.
User.java
//modèle
final class User {
private final long id;
private final String name;
private final int age;
private final Gender gender;
private final String avatarUrl;
private final Email email;
User(long id, String name, int age, Gender gender,
String avatarUrl, Email email) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.avatarUrl = avatarUrl;
this.email = email;
}
}
UserRepository.java
//Classe à l'aide d'un modèle
class UserRepository {
User findBy(long id) {
return null; // TODO
}
List<User> findAll() {
return null; // TODO
}
void store(User user) {
// TODO
}
}
Quand j'essaye d'écrire ce test Repository
, je pense qu'il ressemble à ceci:
UserRepository.java
public class UserRepositoryTest {
private UserRepository repo;
@Before public void setUp() {
repo = new UserRepository();
}
@Test public void store() {
long id = 100;
User expected = new User(id, "", 1, Gender.MALE, "", new Email(""));
repo.store(expected);
User actual = repo.findBy(id);
assertThat(actual, is(equalTo(expected)));
}
@Test public void findAll() {
repo.store(new User(1, "", 1, Gender.MALE, "", new Email("")));
repo.store(new User(2, "", 1, Gender.MALE, "", new Email("")));
List<User> actual = repo.findAll();
assertThat(actual.size(), is(2));
}
}
Je pense que le problème avec ce code de test est la ** partie d'instanciation de classe ʻUser` **. Voici pourquoi.
--ʻLe code est difficile à voir car il y a de nombreux arguments dans le constructeur de la classe User`.
est au centre du test. «Qu'est-ce qui est important est« id »? Ou est-ce tout? ――Vulnérable pour changer le constructeur de la classe User
--Le test ne peut pas être exécuté sans modifier tout le code de test qui utilise le constructeur.Les deux peuvent être une responsabilité pour le fonctionnement à long terme du code de test.
Pour résoudre les problèmes ci-dessus, nous préparerons une classe spécialisée dans la création de données pour la classe ʻUser` à des fins de test. Cela s'appelle le modèle ** Test Data Builder **.
Le fait est que ** les variables membres de cette classe ont des valeurs par défaut définies **.
UserDataBuilder.java
class UserDataBuilder {
private long id = 1;
private String name = "name";
private int age = 20;
private Gender gender = Gender.MALE;
private String avatarUrl = "avatarUrl";
private Email email = new EmailDataBuilder().build();
public User build() {
return new User(id, name, age, gender, avatarUrl, email);
}
public UserDataBuilder withId(long id) {
this.id = id;
return this;
}
public UserDataBuilder withName(String name) {
this.name = name;
return this;
}
...réduction...
public UserDataBuilder withEmail(Email email) {
this.email = email;
return this;
}
}
En utilisant cette classe ʻUserDataBuilder`, si vous modifiez le code de test ci-dessus, ce sera comme suit.
UserRepositoryTest.java
public class UserRepositoryTest {
private UserRepository repo;
@Before public void setUp() {
repo = new UserRepository();
}
@Test public void store() {
long id = 100;
User expected = new UserDataBuilder().withId(id).build();
repo.store(expected);
User actual = repo.findBy(id);
assertThat(actual, is(equalTo(expected)));
}
@Test public void findAll() {
UserDataBuilder user = new UserDataBuilder();
repo.store(user.withId(1).build());
repo.store(user.withId(2).build());
List<User> actual = repo.findAll();
assertThat(actual.size(), is(2));
}
}
Qu'est-ce que tu penses. Comparé au code de test qui n'utilise pas de modèles, ce code est
Je pense qu'il y a un tel mérite.
La classe ʻUser` utilisée dans cet exemple était un objet relativement facile à instancier. Cependant, dans le développement réel, il existe de nombreuses classes dépendantes et de nombreux cas où il est difficile de préparer des données de test. À ce moment-là
Pour écrire le code de test Pourquoi ne pas appliquer ce ** modèle Test Data Builder **?
Recommended Posts