Dieser Artikel ist der 17. Tag von Android 2 Adventskalender 2016 - Qiita.
Heute, als eines der nützlichen Muster für die Pflege von Testcode, Ich möchte das ** Test Data Builder-Muster ** einführen.
Während der eigentlichen Entwicklung Sie schreiben häufig Testcode für Klassen, die Modelle verwenden (z. B. Wertobjekte). In diesem Fall lautet das Wertobjekt dieses Mal "User" und die Klasse, die es verwendet, "UserRepository". Fahren wir mit der Geschichte als Beispiel fort.
User.java
//Modell-
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
//Klasse mit einem Modell
class UserRepository {
User findBy(long id) {
return null; // TODO
}
List<User> findAll() {
return null; // TODO
}
void store(User user) {
// TODO
}
}
Wenn ich versuche, diesen "Repository" -Test zu schreiben, sehe ich folgendermaßen aus:
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));
}
}
Ich denke, das Problem mit diesem Testcode ist der Instanziierungsteil der Klasse ** User
**.
Hier ist der Grund.
User
-Klasse sich der Test konzentriert.
――Was ist wichtig, ist id
? Oder ist das alles?Beides kann eine Haftung für den Langzeitbetrieb des Testcodes sein.
Um die oben genannten Probleme zu beheben, bereiten wir eine Klasse vor, die sich auf das Erstellen von Daten für die Klasse "Benutzer" zum Testen spezialisiert hat. Dies wird als ** Test Data Builder ** -Muster bezeichnet.
Der Punkt ist, dass ** für die Mitgliedsvariablen dieser Klasse Standardwerte festgelegt sind **.
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;
}
...Kürzung...
public UserDataBuilder withEmail(Email email) {
this.email = email;
return this;
}
}
Wenn Sie diese UserDataBuilder-Klasse verwenden und den vorherigen Testcode ändern, ist dies wie folgt.
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));
}
}
Was denken Sie. Im Vergleich zu dem Testcode, der keine Muster verwendet, ist dieser Code
User
KlasseIch denke, es gibt so einen Verdienst.
Die in diesem Beispiel verwendete Klasse "Benutzer" war ein Objekt, das relativ einfach zu instanziieren war. In der tatsächlichen Entwicklung gibt es jedoch viele abhängige Klassen, und es gibt viele Fälle, in denen es schwierig ist, Testdaten vorzubereiten. Zu jener Zeit
Testcode schreiben Wie wäre es mit der Anwendung dieses ** Test Data Builder-Musters **?
Recommended Posts