[test] jpa를 이용한 respository의 테스트코드

Coastby·2022년 12월 26일
0

문제 해결

목록 보기
17/17
post-custom-banner

PostRepository 삭제 로직 테스트

포스트 삭제는 물리적 삭제가 아니라 논리적 삭제로 구현하였다. 그래서 기본 jpa 메서드인 delete()를 사용하지 않고, 쿼리를 이용해서 post entity의 isDeleted()값을 true로 바꾸고 삭제 날짜를 지정하는 로직을 만들었다.

⌨️ PosrRepository

public interface PostRepository extends JpaRepository<Post, Integer> {
    Page<Post> findByisDeletedFalse(Pageable pageable);
    @Modifying(clearAutomatically = true)
    @Query("UPDATE Post p SET p.isDeleted=TRUE, p.deletedAt=:now WHERE p.id=:id")
    void deletePostById(@Param(value="id") Integer id, @Param(value = "now")Timestamp now);
}

이를 테스트하기 위해 테스트 코드를 작성하였다.

⌨️ PostRepositoryTest

@DataJpaTest
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class PostRepositoryTest {
    @Autowired
    private PostRepository postRepository;

    @Test
    @DisplayName("삭제 로직")
    void delete_post(){
        Timestamp now = new Timestamp(System.currentTimeMillis());
        postRepository.deletePostById(1, now);

        Post post = postRepository.findById(1).orElse(null);

        assertTrue(post.isDeleted());
        assertEquals(post.getDeletedAt(), now);
        assertEquals(post.getId(), 1);
    }
}

1) @DataJpaTest

@DataJpaTest는 Jpa 관련 Configuration만 빈으로 등록하기 때문에 @SpringBootTest보다는 가볍게 실행할 수 있어서 어노테이션을 선택했다. 또한 @DataJpaTest은 기본적으로 @Transactional 어노테이션을 포함하고 있어 테스트 코드가 종료되면 자동으로 데이터베이스의 롤백이 진행된다.

2) @AutoConfigureTestDatabase

@DataJpaTest를 선언하면 자동으로 EmbeddedDatabase를 사용하게 된다. 따라서 현재 사용하는 db인 mysql로 테스트를 하려고 하면 @AutoConfigureTestDatabase(replace = Replace.NONE)을 이용해서 자동 설정되지 않게 한다.

3) @ActiveProfiles("test")

application-test.ymll을 작성하여 jpa와 관련된 변수들을 설정하였다.

참고 : https://kangwoojin.github.io/programing/auto-configure-test-database/

⌨️ application-test.yml

spring:
  sql:
    init:
      mode: always
#      schema-locations: classpath:sql/schema.sql
      data-locations: classpath:sql/data.sql
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: create
    defer-datasource-initialization: true
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: localhost
    username: root
    password: password

jwt:
  token:
    secret: key

⌨️ data.sql

-- user data 삽입
insert into user (id, user_name, password, role)
values (1, 'string', '{bcrypt}$2a$10$LDwzHdFsoeeo0CjXoYdmwelLK4CjdiMtGvPHDYPQ039JEx19L7C8e', 'USER'),
(2, 'string2', '{bcrypt}$2a$10$LDwzHdFsoeeo0CjXoYdmwelLK4CjdiMtGvPHDYPQ039JEx19L7C8e', 'USER');
-- post data 삽입
insert into post (id, body, is_deleted, title, user_id)
values (1, "body", false, "title", 1),
(2, "body2", false, "title2", 1);
profile
훈이야 화이팅
post-custom-banner

0개의 댓글