테스트 코드 세션(레포지토리, 컨트롤러 유닛 테스트)
dependencies {
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql'
}
@Testcontainers
@SpringBootTest
class MyRepositoryTest {
//랜덤포트로 띄운다!
@Container
static MySQLContainer<?> mysql =
new MySQLContainer<>("mysql:8.0")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");;
@DynamicPropertySource
static void configure(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", mysql::getJdbcUrl);
registry.add("spring.datasource.username", mysql::getUsername);
registry.add("spring.datasource.password", mysql::getPassword);
}
@Container
static GenericContainer<?> redis =
new GenericContainer<>("redis:7")
.withExposedPorts(6379);
registry.add(
"spring.data.redis.port",
() -> redis.getMappedPort(6379)
);
package com.example.demo.repository;
import com.example.demo.entity.User;
import com.example.demo.entity.UserRole;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@DataJpaTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
@DisplayName("이메일로_사용자를_조회할_수_있다")
void 이메일로_사용자를_조회할_수_있다() {
// given
String email = "asd@asd.com";
User user = new User(email, "password", UserRole.USER);
userRepository.save(user);
// when
User foundUser = userRepository.findByEmail(email).orElse(null);
// then
assertNotNull(foundUser);
assertEquals(email, foundUser.getEmail());
assertEquals(UserRole.USER, foundUser.getUserRole());
// 강의 방식
assertThat(foundUser).isNotNull();
// 잘 모르겠으면 assertThat 하고 찾아보면 됨
}
}
package com.example.demo.service;
import com.example.demo.dto.UserResponse;
import com.example.demo.entity.User;
import com.example.demo.entity.UserRole;
import com.example.demo.exception.InvalidRequestException;
import com.example.demo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock // 테스트대상이 아님
private UserRepository userRepository;
@InjectMocks //테스트 대상임
private UserService userService;
@Test
void User를_ID로_조회할_수_있다() {
// given
String email = "asd@asd.com";
long userId = 1L;
User user = new User(email, "password", UserRole.USER);
ReflectionTestUtils.setField(user, "id", userId);
given(userRepository.findById(anyLong())).willReturn(Optional.of(user));
// when
UserResponse userResponse = userService.getUser(userId);
// then
assertThat(userResponse).isNotNull();
assertThat(userResponse.getId()).isEqualTo(userId);
assertThat(userResponse.getEmail()).isEqualTo(email);
}
@Test
void 존재하지_않는_User를_조회_시_InvalidRequestException을_던진다() {
// Given
long userId = 1L;
given(userRepository.findById(anyLong())).willReturn(Optional.empty());
// When & Then
assertThrows(InvalidRequestException.class,
() -> userService.getUser(userId),
"User not found"
);
}
@Test
void User를_삭제할_수_있다() {
// given
long userId = 1L;
// anyLong: 어떤 Long 타입 값이 와도 상관없다 given(userRepository.existsById(anyLong())).willReturn(true);
doNothing().when(userRepository).deleteById(anyLong());
// when
userService.deleteUser(userId);
// then
verify(userRepository, times(1)).deleteById(userId);
}
@Test
void 존재하지_않는_User를_삭제_시_InvalidRequestException를_던진다() {
// given
long userId = 1L;
given(userRepository.existsById(userId)).willReturn(false);
// when & then
assertThrows(InvalidRequestException.class, () -> userService.deleteUser(userId));
verify(userRepository, never()).deleteById(userId);
}
}
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean // 깡통
private UserService userService;
@Test
void User_목록_조회_빈리스트() throws Exception {
// given
given(userService.getUsers()).willReturn(List.of());
// when & then
mockMvc.perform(get("/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$").isEmpty());
}
@Test
void User_목록_조회() throws Exception {
// given
long userId1 = 1L;
long userId2 = 2L;
String email1 = "user1@a.com";
String email2 = "user2@a.com";
List<UserResponse> userList = List.of(
new UserResponse(userId1, email1),
new UserResponse(userId2, email2)
);
given(userService.getUsers()).willReturn(userList);
// when & then
mockMvc.perform(get("/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(2))
.andExpect(jsonPath("$[0].id").value(userId1))
.andExpect(jsonPath("$[0].email").value(email1))
.andExpect(jsonPath("$[1].id").value(userId2))
.andExpect(jsonPath("$[1].email").value(email2));
}
@Test
void User_단건_조회() throws Exception {
// given
long userId = 1L;
String email = "a@a.com";
given(userService.getUser(userId)).willReturn(new UserResponse(userId, email));
// when & then
mockMvc.perform(get("/users/{userId}", userId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(userId))
.andExpect(jsonPath("$.email").value(email));
}
