
주 목적은 오류를 줄이고 버그에 빠르게 대처하기위해서이다.
스프링에서는 단위 테스트와 통합테스트가 있다.
Given/When/Then 패턴
Given : 어떠한 데이터가 주어질 때.
When : 어떠한 기능을 실행하면.
Then : 어떠한 결과를 기대한다.
@Test
@DisplayName("TestName")
void test() {
// Given
// When
// Then
}
단위테스트는 하나의 기능 또는 메서드를 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트
일반적인 테스트 코드 작성
테스트하고자 하는 부분만 독립적으로 테스트를 진행
-> 빠른 작성과 문제 여부를 확인
독립적인 테스트 즉, 다른 객체와 데이터를 주고 받는 경우에 문제가 발생
기능과 연관된 모듈에서 가짜 데이터, 정해진 반환값을 넣어주어야함
다른 객체들과 데이터를 주고받으며 기능이 수행 될때, 연관된 객체들과 올바르게 동작하는지 검증
단위 테스트와는 달리 주로 연관기능 동작 확인하며 실제 운영 환경과 유사한 조건에서 테스트를 수행한다.
전반적인 동작과 상호작용을 검증하는 것이기에 엄청나게 긴 시간이 소요되며 에러가 났을 때 어디서 나는 에러인지 감을 잡기가 힘들다.
public class DtoTest implements CommonTest {
private Validator validator = null;
@BeforeEach
public void setUp() {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
@Nested
@DisplayName("보드 dto 테스트")
class boardRequestTest{
@Test
@DisplayName("요청 dto 생성 성공")
void boardRequestTest_ok(){
//given
BoardRequestDto boardRequestDto = new BoardRequestDto();
boardRequestDto.setTitle(BOARD_TITLE);
boardRequestDto.setContent(BOARD_CONTENT);
//when
Set<ConstraintViolation<BoardRequestDto>> violations = validator.validate(boardRequestDto);
//then
assertThat(violations).isEmpty();
}
@Test
@DisplayName("Dto 제목 비어있을경우")
void boardRequestTest_badTitle(){
//given
BoardRequestDto boardRequestDto = new BoardRequestDto();
boardRequestDto.setTitle(null);
boardRequestDto.setContent(BOARD_CONTENT);
//when
Set<ConstraintViolation<BoardRequestDto>> violations = validator.validate(boardRequestDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message").contains("제목을 입력해주세요.");
}
@Test
@DisplayName("Dto 내용 비어있을경우")
void boardRequestTest_badContent(){
//given
BoardRequestDto boardRequestDto = new BoardRequestDto();
boardRequestDto.setTitle(BOARD_TITLE);
boardRequestDto.setContent(null);
//when
Set<ConstraintViolation<BoardRequestDto>> violations = validator.validate(boardRequestDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message").contains("내용을 입력해주세요.");
}
}
@Nested
@DisplayName("SignRequestDto Test")
class signRequestTest{
@Test
@DisplayName("요청 성공")
void signRequestTest_ok(){
//given
SignupRequestDto signupRequestDto = new SignupRequestDto();
signupRequestDto.setUsername(USERNAME);
signupRequestDto.setPassword(PASSWORD);
signupRequestDto.setNickname(NICKNAME);
signupRequestDto.setEmail(EMAIL);
signupRequestDto.setInfo(INFO);
//when
Set<ConstraintViolation<SignupRequestDto>> violations = validator.validate(signupRequestDto);
//then
assertThat(violations).isEmpty();
}
@Test
@DisplayName("요청 실패(username)")
void signRequestTest_badUsername(){
//given
SignupRequestDto signupRequestDto = new SignupRequestDto();
signupRequestDto.setUsername("INVALIDNAME");
signupRequestDto.setPassword(PASSWORD);
signupRequestDto.setNickname(NICKNAME);
signupRequestDto.setEmail(EMAIL);
signupRequestDto.setInfo(INFO);
//when
Set<ConstraintViolation<SignupRequestDto>> violations = validator.validate(signupRequestDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message").contains("사용자 ID는 최소 10글자 이상, 최대 20글자 이하여야 합니다.");
}
@Test
@DisplayName("요청 실패(password)")
void signRequestTest_badPassword(){
//given
SignupRequestDto signupRequestDto = new SignupRequestDto();
signupRequestDto.setUsername(USERNAME);
signupRequestDto.setPassword("sdfsdfsdf12");
signupRequestDto.setNickname(NICKNAME);
signupRequestDto.setEmail(EMAIL);
signupRequestDto.setInfo(INFO);
//when
Set<ConstraintViolation<SignupRequestDto>> violations = validator.validate(signupRequestDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message").contains("대소문자 포함 영문 + 숫자 + 특수문자를 최소 1글자씩 포함합니다. \n비밀번호는 최소 10글자 이상이어야 합니다.");
}
@Test
@DisplayName("요청 실패(nickname)")
void signRequestTest_badNickname(){
//given
SignupRequestDto signupRequestDto = new SignupRequestDto();
signupRequestDto.setUsername(USERNAME);
signupRequestDto.setPassword(PASSWORD);
signupRequestDto.setNickname(null);
signupRequestDto.setEmail(EMAIL);
signupRequestDto.setInfo(INFO);
//when
Set<ConstraintViolation<SignupRequestDto>> violations = validator.validate(signupRequestDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message").contains("Required Nickname");
}
}
@Nested
@DisplayName("Like Dto Test")
class likeDtoTest{
@Test
@DisplayName("Dto 요청 성공")
void likeDtoTest_ok(){
//given
LikeDto likeDto = new LikeDto();
likeDto.setContentId(CONTENT_ID);
likeDto.setContentType(LIKE_TYPE_ENUM.toString());
//when
Set<ConstraintViolation<LikeDto>> violations = validator.validate(likeDto);
//then
assertThat(violations).isEmpty();
}
@Test
@DisplayName("Dto 요청 실패(id null)")
void likeDtoTest_badId(){
//given
LikeDto likeDto = new LikeDto();
likeDto.setContentId(null);
likeDto.setContentType(LIKE_TYPE_ENUM.toString());
//when
Set<ConstraintViolation<LikeDto>> violations = validator.validate(likeDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message")
.contains("Content ID는 필수입니다.");
}
@Test
@DisplayName("Dto 요청 실패(type)")
void likeDtoTest_badType(){
//given
LikeDto likeDto = new LikeDto();
likeDto.setContentId(CONTENT_ID);
likeDto.setContentType("45623");
//when
Set<ConstraintViolation<LikeDto>> violations = validator.validate(likeDto);
//then
assertThat(violations).hasSize(1);
assertThat(violations).extracting("message")
.contains("영어만 입력 가능합니다.");
}
}
}
public class EntityTest implements CommonTest {
@Nested
@DisplayName("User Entity 테스트")
class UserEntity {
User user;
@BeforeEach
void setUp() {
user = CommonTest.user;
}
@Test
@DisplayName("softDelete Test")
void softDeleteTest() {
//no given
//when
user.softDelete();
//then
assertEquals(user.getStatus(),DELETED);
assertNotNull(user.getDeletedAt());
}
@Test
@DisplayName("updateToken Test")
void updateTokenTest() {
//given
String refreshToken = "test1234";
//when
user.updateToken(refreshToken);
//then
assertEquals(refreshToken, user.getRefreshToken());
}
@Test
@DisplayName("setExpired Test")
void setExpiredTest() {
//given
boolean expired = true;
//when
user.setExpired(expired);
//then
assertEquals(expired, user.isExpired());
}
}
@Nested
@DisplayName("Board Entity 테스트")
class BoardEntity{
Board board;
@BeforeEach
void setUp() {
board = new Board();
}
@Test
@DisplayName("hitsUp Test")
void hitsUpTest() {
//given
board.setHits(0L);
//when
board.hitsUp();
//then
assertEquals(1, board.getHits());
}
@Test
@DisplayName("update Test")
void updateTest() {
//given
BoardRequestDto boardRequestDto = new BoardRequestDto();
boardRequestDto.setTitle("게시물제목");
boardRequestDto.setContent("게시물내용");
//when
board.update(boardRequestDto);
//then
assertEquals("게시물제목", board.getTitle());
assertEquals("게시물내용", board.getContent());
assertNotNull(board.getModifiedAt());
}
}
@Nested
@DisplayName("Comment Test")
class CommentEntity{
Comment comment;
@BeforeEach
void setUp() {
comment = new Comment();
}
@Test
@DisplayName("update Test")
void updateTest() {
//given
CommentRequestDto commentRequestDto = new CommentRequestDto();
commentRequestDto.setContent("댓글내용");
//when
comment.update(commentRequestDto);
//then
assertEquals("댓글내용", comment.getContent());
}
@Test
@DisplayName("delete Test")
void deleteTest() {
//no given
//when
comment.delete();
//then
assertNotNull(comment.getDeletedAt());
}
@Test
@DisplayName("isCommentAuthor Test")
void isCommentAuthorTest() {
//given
User user = new User();
Long userId = 1L;
//when
boolean answer = comment.isCommentAuthor(userId);
//then
assertTrue(true, String.valueOf(answer));
}
}
}
뭔가 검증하는게 더 머리가 아픈 일인거 같다.
엔티티와 DTO 테스트는 그래도 필드 주입하고 예외 처리가 잘 되는지만
체크하면되서 에러가 거의 발생 하지 않았는데
컨트롤러 테스트를 진행하자마자 엄청난 에러 메세지를 보고 있다.
왜 필터관련 에러가 계속 나오는지 알아보아야겠다.