데이터베이스로부터 조회한 값을 연산하는 비즈니스로직을 구현했다고 하면 해당 로직을 테스트하기 위해선 항상 데이터베이스의 영향을 받을 것이고, 이는 데이터베이스의 상태에 따라 다른 결과를 유발할 수 있다.
-> 객체와 연관된 객체를 사용하기가 어렵고 모호할 때 대신해 줄 수 있는 객체를 Test Double이라고 한다.
크게 Dummy, Fake, Stub, Spy, Mock으로 나눠진다.
public interface AccountDao{
void showMember();
}
public class AccountDaoDummy implements AccountDao{
@Override
public void showMember{
//Dummy
}
}
AccountDaoDummy는 아무런 기능을 하지 않고 반환값도 없다. Clinet입장에서는 Dummy를 호출하기만 하면 되는 테스트이므로 내부 동작과는 상관없이 테스트 성공함
LoginService를 테스트하기 위해서는 AccountDao가 필요하다. 하지만 아직 구현되지 않았거나 독립적으로 미리 테스트하고 싶다면 Fake객체를 사용해서 FakeAccountDao객체는 임의의 Map를 생성하여 진짜인 것처럼 Service가 보낸 메세지에 반응한다.
public class FakeAccountRepository implements AccountRepository {
Map<User, Account> accounts = new HashMap<>();
public FakeAccountRepository() {
this.accounts.put(new User("john@bmail.com"), new UserAccount());
this.accounts.put(new User("boby@bmail.com"), new AdminAccount());
}
String getPasswordHash(User user) {
return accounts.get(user).getPasswordHash();
}
}
실제 데이터베이스 설계를 연기하면서 테스트를 신속하게 실행
@Before
public void setUp() throws Exception {
gradebook = mock(Gradebook.class);
student = new Student();
}
@Test
public void calculates_grades_average_for_student() {
when(gradebook.gradesFor(student)).thenReturn(grades(8, 6, 10)); //stubbing gradebook
double averageGrades = new GradesService(gradebook).averageGrades(student);
assertThat(averageGrades).isEqualTo(8.0);
}
실제 객체 대신 Stub(when을 이용하여 반환할 데이터를 미리 정의)을 도입하고 어떤 데이터를 반환해야 하는지 정의 후 리턴
public class MailingService {
private int sendMailCount = 0;
private Collection<Mail> mails = new ArrayList<>();
public void sendMail(Mail mail) {
sendMailCount++;
mails.add(mail);
}
public long getSendMailCount() {
return sendMailCount;
}
}
Mockito 프레임워크의 verify()메서드가 같은 역할을 한다.
@Test
public void mockTest(){
List mockedList = mock(List.class);
// 행위 추가
mockedList.add("one");
mockedList.clear();
// 행위 검증
verify(mockedList).add("one");
verify(mockedList).clear();
}
테스트를 진행한다면 위의 항목들 중에서 어떤 테스트 더블이 필요할지 결정하고, 결정한 테스트가 경계를 벗어나는지 보며 가능한 최소한의 테스트를 선택해야 한다.
순서대로 Dumny -> Stub -> Fake -> Spy -> Mock
https://codinghack.tistory.com/92
https://tecoble.techcourse.co.kr/post/2020-09-19-what-is-test-double/