읽기 좋은 테스트 코드는
마치 책을 읽듯이 그냥 술술 읽으면 로직이 이해되는 그런 코드이다.
(물론, 영어를 기준으로 하기 때문에 비영어권 개발자로서 그닥 빠르게 이해되진 않지만-ㅅ-)
@RunWith(MockitoJUnitRunner.class)
public class PermissionTest {
@Test
public void hasPermissionWhenFriend() {
when(daoProvider.get("key")).thenReturn(dao);
when(dao.areFriends("id")).thenReturn(true);
assertTrue(dut.hasPermission());
}
@Test
public void hasPermissionWhenNotFriend() {
when(daoProvider.get("key")).thenReturn(dao);
when(dao.areFriends("id")).thenReturn(false);
assertFalse(dut.hasPermission());
}
}
위 코드를 아래 코드처럼 수정해봤다.
@RunWith(MockitoJUnitRunner.class)
public class PermissionTest {
private static final boolean ACCEPT = true;
private static final boolean DENY = false;
private static final boolean FRIEND = true;
private static final boolean NOT_FRIEND = false;
@Test
public void hasPermissionWhenFriend() {
givenFriendCondition(FRIEND);
boolean permission = dut.hasPermission();
assertThat(permission, is(ACCEPT));
}
@Test
public void hasPermissionWhenNotFriend() {
givenFriendCondition(NOT_FRIEND);
boolean permission = dut.hasPermission();
assertThat(permission, is(DENY));
}
private void givenFriendCondition(boolean areFriends) {
when(daoProvider.get("key")).thenReturn(dao);
when(dao.areFriends("id")).thenReturn(areFriends);
}
}
static final 의 필드 변수를 저렇게(실제로직에는 좀더 많이) 많이 쓰는 것이 좋은지는 모르겠다.
실제 코드에서는 상수형으로 쓸 static final 필드 변수는 enum 객체로 관리하라고 권장하니까.
그래도 부담이 많은 실제 로직이 아니라 단순히 테스트 케이스이고,
또, 읽기에는 더 좋으니 그냥 저렇게 했다.
특히 Mock 객체의 given 조건을 별도의 private 메소드로 분리하면서
실제 테스트 코드는 거의 3줄 정도이면 된다. (given, when, then)
덧. 중간중간에 주요 부분을 빠뜨린 코드이므로 Copy&Paste로 컴파일되지는 않음.