이 시리즈는 TDD를 숙달하기 전에 TEST 자체에 대한 이해를 높이기 위한 학습 시리즈입니다
System under test
: 테스트하려는 대상을 뜻합니다@Test
void 유저는_북마크를_toggle_추가_할_수_있다() {
// given
User sut = User.builder()
.bookmark(new ArrayList<>())
.build();
// when
sut.toggleBookmark("my-link");
// then
boolean result = user.hasBookmark("my-link");
assertThat(result).isTrue();
Behaviour driven development(given-when-then)
BDD
입니다@Test
void 유저는_북마크를_toggle_추가_할_수_있다() {
// given
User sut = User.builder()
.bookmark(new ArrayList<>())
.build();
// when
sut.toggleBookmark("my-link");
// then
boolean result = user.hasBookmark("my-link");
assertThat(result).isTrue();
// Interaction test
verify(sut).markModified();
협력 객체의 어떤 메서드를 실행하는가
자원
을 생성하는 것private User sut;
@BeforeEach
void 사용자를_미리_할당합니다() {
sut = User.builder()
.bookmark(new ArrayList<>())
.build();
@Test
void 유저는_북마크를_toggle_삭제_할_수있다() {
// given
sut.appendBookmark("my-link");
// when
sut.toggleBookmark("my-link");
// then
assertThat(sut.hasBookmark("my-link")).isTrue();
verify(sut).removeBookmark; // Interaction test
@Test
public void 이메일_회원가입을_할_수_있다() {
// given
UserCreateRequest userCreateRequest = UserCreateRequest.builder()
.email("foo@localhost.com")
.password("123445")
.build();
// when
UserService sut = UserService.builder()
.registerEmailSender(new DummyEmailSender())
.userRepository(userRepository)
.build();
sut.register(userCreateRequest);
// then
User user = userRepository.getByEmail("foo@localhost.com");
assertThat(user.isPending()).isTrue();
}
DummyEmailSender
가 아무런 동작도 하지 않는 dummy
의 종류입니다class DummyEmailSender implements RegisterEmailSender {
@override
public void send(String email, String message) {
// do nothing
}
}
dummy
와 다르게 자체 로직을 가지고 있다는 게 특징입니다Local
에서 사용하거나 테스트에서 사용하기위해 만들어진 가짜 객체class FakeRegisterEmailSender implements RegisterEmailSender {
private final Map<String, List<String>> latestMessages = new HashMap<>();
@override
public void send(String email, String message) {
List<String> records = latestMessages.getOrDefault(email, new ArrayList<>());
records.add(message);
latestMessages.put(email, records);
}
public Opional<String> findLatestMessage(String email) {
return latestMessages.getOrDefault(email, new ArrayList<>())
.stream()
.findFirst();
}
}
@Test
public void 이메일_회원가입을_할_수_있다() {
// given
UserCreateRequest userCreateRequest = UserCreateRequest.builder()
.email("foo@localhost.com")
.password("123445")
.build();
FakeRegisterEmailSender registerEmailSender = new FakeRegisterEmailSender();
// when
UserService sut = UserService.builder()
.registerEmailSender(registerEmailSender)
.userRepository(userRepository)
.build();
sut.register(userCreateRequest);
// then
User user = userRepository.getByEmail("foo@localhost.com");
assertThat(user.isPending()).isTrue();
assertThat(registerEmailSender.findLatestMessage("foo@localhost.com")
.isPresent()).isTrue();
assertThat(registerEmailSender.findLatestMessage("foo@localhost.com")
.get()).isEqualTo("~~~");
fake
대역은 메시지를 latestMessages
에 들고 있는 로직을 구현하고 있습니다class StubUserRepository implements UserRepository {
public User getByEmail(String email) {
if (email.equals("foo@localhost.com")) {
return User.builder()
.email("foo@localhost.com")
.status("PENDING")
.build();
}
throw new UsernameNotFoundException(email);
}
}
mockito
프레임워크를 사용해서 구현합니다// given
given(userRepository.getByEmail("foo@bar.com")).willReturn(User.builder()
.email("foo@bar.com")
.status("PENDING")
.build());
// when
// do something
// then
// result something
dummy
, fake
, stub
등도 모두 mock
이라고 칭해지고 있습니다