테스트에서 나를 괴롭혔던 것들

June·2022년 4월 7일
0

우테코

목록 보기
29/84

문제 상황

테스트를 돌리는데 이슈들이 있었다.
1. GameDao에서 테스트를 돌리는데 어떨 때는 성공을하고 어떨 때는 실패를 하는 문제가 있었다.

  1. BoardDao에서 테스트를 돌리는데 체스 말을 움직이므로 매 테스트를 돌린 후 DB에서 되돌리는 작업을 해줘야 한다. connection.setAutoCommit(false); 을 하면 commit이 반영안된다는 걸 듣고 시도해보았는데 여전히 문제가 있었다.

원인 및 해결 1

원인은 GameDaoTestgetTurn() 을 테스트하는 부분이 있고, changeTurn() 메서드가 같이 있는 것에 있었다. changeTurn() 에서 턴을 실제로 바꾸므로 getTurn()이 나중에 실행되면 결과가 달라진다. JUnit5에서 테스트 메서드들의 순서는 메서드 순으로 실행되지 않는다. 그래서 순서가 중요한 테스트라면 순서를 명시해줘야 한다.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class GameDaoTest {

    ...

    @Order(1)
    @Test
    void getTurn() {
        GameDaoImpl gameDao = new GameDaoImpl();
        TurnDto turnDto = gameDao.getTurn();
        assertThat(turnDto.getTurn()).isEqualTo("WHITE");
    }

    @Order(2)
    @Test
    void changeTurn() {
        GameDaoImpl gameDao = new GameDaoImpl();
        TurnDto beforeTurnDto = gameDao.getTurn();

        gameDao.changeTurn();

        TurnDto afterTurnDto = gameDao.getTurn();

        assertThat(beforeTurnDto.getTurn()).isNotEqualTo(afterTurnDto.getTurn());
    }

    ...
}

원인 및 해결 2

BoardDao 에서 말을 움직이는 테스트를 하며 실제로 DB가 변경이된다. 생각한 방법은 두 가지다.

  1. 테스트용 DB 테이블을 만들기
  2. 테스트 후 실제로 되돌리기
class BoardDaoTest {

    ...

    @AfterAll
    static void afterAll() {
        BoardDaoImpl boardDao = new BoardDaoImpl();
        boardDao.movePiece(new CommandDto("a3 a2"));
    }
}

그래서 실행 후 되돌리는 작업을 붙여주었다.

번외

connection.setAutoCommit(false); 을 쓰면 커밋이 되지 않아 DB에 영향을 주지 않는다고 잘못 이해했다.

커넥션이 생겼을 때 디폴트가 auto-commit 모드다. 이건 각각의 SQL 구문이 하나의 트랜잭션으로 취급되고 각각이 실행되고 나서 자동적으로 커밋된다. 그래서 커밋을 모아서 할 수 있게 하는 것이 con.setAutoCommit(false);

만약 내가 원하는데로 테스트 후 데이터베이스가 원래 상태로 돌아가기를 원했다면, 직접 save point를 걸고 rollback을 호출해줘야 한다. connection.setAutoCommit(false);만으로 저절도 되는 것이 아니다.

문서 참조

배운 점

실제 DB와 연동한 테스트를 할 때는 고려할 점이 더 많다라는 것을 알게되었다. 테스트의 순서뿐만 아니라 실제 데이터베이스에 영향을 주지 않게 하는 것도 고려해야 한다.

0개의 댓글