SSAFY11th-book-study / book-study

SSAFY 11기 6반의 '토비의 스프링 스터디'
0 stars 0 forks source link

[2.4.2] 수동 DI를 이용한 UserDao 빈의 의존관계 강제 변경 #18

Closed a-young-kim closed 8 months ago

a-young-kim commented 8 months ago

p.193


@DirtiesContext
public class UserDaoTest {

    @Autowired
    private UserDao dao;
    private User user1, user2, user3;
    @Before
    public void setUp(){

// 테스트에서 UserDao가 사용할 DataSource 오브젝트를 직접 생성한다.
        DataSource dataSource = new SingleConnectionDataSource(
                url, userName, password, true
        );
}

이 테스트 코드는

애플리케이션 컨텍스트에서 가져온 UserDao 빈의 의존관계를 setDataSource() 메소드를 사용하여 강제로 변경하는데 한 번 변경하면 나머지 모든 테스트를 수행하는 동안 변경된 애플리케이션 컨텍스트가 계속 사용될 것입니다. 따라서 @DiritesContext라는 어노테이션을 추가하여 테스트 메소드를 수행하고 나면 매번 새로운 애플리케이션 컨텍스트를 만들어 다음 테스트가 사용하게 해준다.

라고 설명되어 있습니다. 하지만 setUp()이라는 메소드는 @Before 어노테이션으로 인해 테스트 메소드가 실행하기 전에 무조건 실행되어야 하는 메소드라고 알고 있는데 그러면 항상 context가 변경되는 것 아닌가요?? 또한, 해당 어노테이션이 있지 않아도 SingleConnectionDataSource이 테스트 메소드가 실행될 때 생성되어서 영향을 주지 않을 것이라고 생각이 들었습니다.

limjongheok commented 8 months ago

image xml 파일에서 미리 생성해둔 applicationContext 를 가져오고@DirtiesContext 를 통해 @Before 에서는 @Bean userDaO 를 변경 (재구성) 해주는 것 같습니다.

gmelon commented 8 months ago
  1. setUp()이라는 메소드는 \@before 어노테이션으로 인해 테스트 메소드가 실행하기 전에 무조건 실행되어야 하는 메소드라고 알고 있는데 그러면 항상 context가 변경되는 것 아닌가요?? -> 저도 동일하게 이해했습니다.

  2. 해당 어노테이션이 있지 않아도 SingleConnectionDataSource이 테스트 메소드가 실행될 때 생성되어서 영향을 주지 않을 것이라고 생각이 들었습니다 -> 이 부분은 현재 테스트 클래스가 아닌 다른 테스트 클래스를 실행할 때 문제가 된다고 이해했습니다. 만약 \@DirtiesContext 가 없다면, 현재 테스트 클래스는 SingleConnectionDataSource를 테스트에 사용할 것이고 매번 초기화해주니 문제되지 않겠지만 현재 클래스에서 테스트가 진행된 이후 동일한 애플리케이션 컨텍스트를 공유하는 (DataSource를 별도로 다시 초기화해주는지 확신할 수 없는) 다른 테스트 클래스의 테스트 메서드를 실행하게 되면 해당 테스트는 테스트용 SingleConnectionDataSource 를 사용해야 하는지 xml에 기본 설정된 빈을 사용해야 하는지 알 수 없기 때문에 컨텍스트의 상태를 변경하는 것이 위험하다고 이해했습니다.

gmelon commented 8 months ago
a-young-kim commented 8 months ago
  1. @DiritesContext이 있지 않아도 SingleConnectionDataSource이 테스트 메소드가 실행될 때 생성되어서 영향을 주지 않을 것이라고 생각이 들었습니다. 해당 어노테이션이 필요한 이유가 무엇일까요? 답: 해당 테스트 클래스만 실행할 경우에는 @Before에서 새로운 DataSource를 생성하므로 오류가 발생하지는 않지만 여러 테스트 클래스를 실행할 경우 오류가 발생할 수 있습니다. DataSource를 @Before에서 초기화하지 않는 다른 클래스 경우 UserDaoTest 완료 후 변경된 context가 사용될 수 있기 때문에 @DirtiesContext를 사용해야합니다.

    1. 여러 테스트 클래스가 실행될 때 한 클래스의 테스트 메소드가 모두 실행되고 나서 다른 테스트 클래스가 실행되나요? 답: 한 클래스의 테스트 메소드가 모두 실행되고 나서 다른 테스트 클래스가 실행된다고 보장할 수 없습니다. 스프링은 테스트 클래스의 병렬 실행을 지원하는데 이러한 경우에는 순서대로 실행되지 않습니다.