Service Layer Test와 Controller Layer Test는 구현하는데 차이점이 있다. 서비스 레이어는 웹 레이어와 관련이 없으므로 WebMvcTest 어노테이션을 사용하지 않는다.
서비스 레이어 테스트 코드 작성 방식중 SpringBootTest(classes = *)를 사용하는 방법과 mockito를 사용하는 방식이 있다. mockito를 사용하면 서비스 레이어에서만 독립적으로 테스트 할 수 있어 객체간 의존성이 사라진다. 또 SpringBootTest를 사용하지 않음으로서 서버를 동작하지 않고 테스트를 진행할 수 있다.
Mockito를 이용하여 작성한 방법을 설명하겠다. 먼저 작성한 테스트 코드이다.
@RunWith(SpringRunner.class)
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Mock
private UserRepository userRepository;
private User user;
private UserDTO userDTO;
private static final Long newID = 0L;
@Before
public void setUp() {
userDTO = new UserDTO();
userDTO.setUserId("admin");
userDTO.setPw("admin");
userDTO.setName("lcy");
userDTO.setAge(25);
user = User.builder()
.id(newID)
.userId(userDTO.getUserId())
.pw(userDTO.getPw())
.name(userDTO.getName())
.age(userDTO.getAge())
.build();
}
@Test
public void createUser() {
//mocking, given
given(userRepository.save(any())).willReturn(user);
// when(userRepository.save(any())).thenReturn(user);
//when
Long id = userService.createUser(userDTO);
//then
verify(userRepository).save(any());
assertThat(id).isNotNull();
}
}
@ExtendWith(MockitoExtension.class) 어노테이션을 사용하여 @Mock 어노테이션이 붙은 객체를 목객체로 초기화하고 @InjectMocks가 붙어있는 객체에는 목객체로 의존을 주입한다.
서비스와 의존성이 있는 UserRepository를 Mock객체로 선언한다.
서비스는 InjectMocks로 의존을 주입한다.
@Befors
@Test
then 영역에서 assert문을 사용할때는 assertj의 assertThat을 사용하는것이 가독성이 좋고 사용하기도 편하다고 한다. 간단한 사용방법에 대해선 아래의 사이트를 참고하고 보다 나은 기능은 문서를 참조하도록 하자.