Mockito : Mock 객체를 쉽게 만들고, 관리하고, 검증할 수 있는 방법을 제공하는 프레임워크 입니다. Mock 객체는 진짜 객체와 비슷하게 동작하지만 프로그래머가 직접 행동을 관리하는 객체입니다.
@Mock
: Mock 객체를 만들어 반환해주는 어노테이션@Spy
: Stub하지 않은 메소드들은 원본 메소드 그대로 사용하는 어노테이션@InjectMocks
: @Mock 또는 @Spy로 생성된 가짜 객체를 자동으로 주입시켜주는 어노테이션@ExtendWith(MockitoExtension.class)
: JUnit 과 Mockito 연결
@Mock
: 가짜! -> repository ..
@Spy
: 진짜! -> jwt, password ..
@injectMocks
: mock이든 spy이든 여기다 주입
given : when에서 사용할 파라미터 지정 -> RequestDto
when : 진짜 테스트 시작
then : 검증
HttpServletResponse or HttpServletRequest 와 같은 경우는 앞에 Mock 을 붙혀 사용 하면 된다. -> given
package com.sparta.blogproject.user.service;
import com.sparta.blogproject.common.jwt.JwtUtil;
import com.sparta.blogproject.user.dto.LoginRequest;
import com.sparta.blogproject.user.dto.ResponseStatusDto;
import com.sparta.blogproject.user.dto.SignupRequest;
import com.sparta.blogproject.user.dto.StatusEnum;
import com.sparta.blogproject.user.entity.User;
import com.sparta.blogproject.user.repository.UserRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Spy
private JwtUtil jwtUtil;
@Spy
private BCryptPasswordEncoder passwordEncoder;
@Test
@DisplayName("회원 가입")
void signup() {
// given
SignupRequest request = SignupRequest.builder()
.admin(false)
.username("nathan")
.password("1234qwer")
.email("nathan@gmail.com")
.build();
when(userRepository.findByUsername(any(String.class)))
.thenReturn(Optional.empty());
// when
ResponseStatusDto response = userService.signup(request);
// then
assertThat(response.getStatusCode()).isEqualTo(StatusEnum.SIGN_SUCCESS.getStatusCode());
assertThat(response.getMsg()).isEqualTo(StatusEnum.SIGN_SUCCESS.getMsg());
}
@Test
@DisplayName("로그인")
void login() {
// given
LoginRequest request = LoginRequest.builder()
.username("nathan")
.password("1234qwer")
.build();
User user = new User("nathan", passwordEncoder.encode("1234qwer"), null, null);
when(userRepository.findByUsername(any(String.class)))
.thenReturn(Optional.of(user));
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
// when
ResponseStatusDto response = userService.login(request, servletResponse);
// then
assertThat(response.getStatusCode()).isEqualTo(StatusEnum.LOGIN_SUCCESS.getStatusCode());
assertThat(response.getMsg()).isEqualTo(StatusEnum.LOGIN_SUCCESS.getMsg());
assertThat(servletResponse.getHeaderValue("Authorization").toString()).isNotEmpty();
verify(userRepository).saveAndFlush(any(User.class));
}
}
package com.sparta.blogproject.post.service;
import com.sparta.blogproject.post.dto.PostRequestDto;
import com.sparta.blogproject.post.dto.PostResponseDto;
import com.sparta.blogproject.post.entity.Post;
import com.sparta.blogproject.post.repository.PostRepository;
import com.sparta.blogproject.user.entity.User;
import org.junit.jupiter.api.DisplayName;
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.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class PostServiceTest {
@Mock
private PostRepository postRepository;
@InjectMocks
private PostService postService;
@Test
void createPost() {
// given
PostRequestDto request = new PostRequestDto();
User user = new User();
// when
postService.createPost(request, user);
// then
verify(postRepository).save(any(Post.class));
}
@Test
void getPosts() {
// given
Pageable pageable = Pageable.ofSize(20);
when(postRepository.findAll(pageable)).thenReturn(Page.empty());
// when
Page<PostResponseDto> response = postService.getPosts(pageable);
// then
assertThat(response).isEmpty();
// verify
verify(postRepository).findAll(pageable); // findAll이 호출 되었는가?
}
@Test
@DisplayName("게시글 id가 없을때 예외 발생")
void getPostById_throw() {
// given
when(postRepository.findById(anyLong())).thenReturn(Optional.empty());
// when & then
assertThrows(IllegalArgumentException.class, () -> {
postService.getPostById(0L);
}); // 다른 예외로 지정시 실패
}
@Test
@DisplayName("게시글 가져오기")
void getPostById() {
// given
PostRequestDto request = PostRequestDto.builder()
.contents("hello.. hello..")
.title("hello")
.build();
Post post = new Post(request, new User());
when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); //id가 테스트 할 때에는 의미가 없기 때문에 anylong
// when
PostResponseDto response = postService.getPostById(anyLong());
// then
assertThat(response.getContents()).isEqualTo(request.getContents());
assertThat(response.getTitle()).isEqualTo(request.getTitle());
// verify
verify(postRepository, times(1)).findById(anyLong());
}
@Test
@DisplayName("게시글 업데이트")
void updatePost() {
// given
PostRequestDto request = PostRequestDto.builder()
.contents("hello.. hello..")
.title("hello")
.build();
User user = new User("nathan", "1234qwer", null, null);
Post post = new Post(request, user);
when(postRepository.findById(anyLong())).thenReturn(Optional.of(post));
// when
postService.updatePost(anyLong(), request, user);
// verify
verify(postRepository, times(1)).save(any(Post.class));
}
@Test
@DisplayName("게시글 업데이트 (다른 사람이 작성하려할때)")
void updatePost_invalid_user() {
// given
PostRequestDto request = PostRequestDto.builder()
.contents("hello.. hello..")
.title("hello")
.build();
User userInPost = new User("nathan", "1234qwer", null, null);
User userInput = new User("joel", "1234qwer", null, null);
Post post = new Post(request, userInPost);
when(postRepository.findById(anyLong())).thenReturn(Optional.of(post));
// when & then
assertThrows(IllegalArgumentException.class, () -> postService.updatePost(anyLong(), request, userInput));
}
}