빈이 많아지고 복잡해지면 ApplicationContext 생성에 적지 않은 시간이 걸릴 수 있다. ApplicationContext가 만들어질 때 모든 싱글톤 빈 오브젝트를 초기화하는데, 이 작업이 많은 시간이 소요된다.
이 문제를 해결하기 위해서 ApplicationContext를 static 레벨에 저장해두는 방법도 있지만, 스프링이 직접 제공하는 ApplicationContext 테스트 지원 기능을 사용하는 것이 편리하다.
@Runwith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/applicationContext.xml")
public class UserDaoTest {
@Autowired
private ApplicationContext context;
@Before
public void setUp() {
this.dao = this.context.getBean("userDao", UserDao.class);
}
}
context를 초기화해주는 코드는 없어서, 메소드에서 context를 사용하려면 NullPointerException이 발생하지만, 테스트에서는 아무런 문제가 발생하지 않는다.
여기서 더 간단하게는, UserDao를 주입받아서 사용할 수도 있다.
public class UserDaoTest {
@Autowired
UserDao dao;
}
DataSource의 구현 클래스를 바꾸지 않고, DB 커넥션의 정보를 바꾸 일이 없는데도, 굳이 인터페이스를 사용해서 DI를 주입해주는 방식을 사용해야 할까?
(매일 고민하는 부분...)
테스트를 하면서 실제 운영되는 DB에 사용자 정보를 수정하거나 삭제하는 일이 벌어진다면???
그러지 않으려면, @DirtiesContext로 ApplicationContext 구성이나 상태를 변경한다는 것을 알리고, DataSource의 정보를 다시 생성해서 사용하는 방법이 있다. 하지만, 이미 주입받은 것을 다시 덮어쓰기?하는 느낌으로
별도의 DI를 설정하는 방법이 있다.
책에서는 xml 파일을 별도로 두고, @ContextConfiguration으로 설정 파일의 정보를 알려주는 방식을 알려주고 있지만, 나는 properties 파일을 적용하고 있어서 찾아보았다.
https://stackoverflow.com/questions/32974432/spring-junit-testing-properties-file
배포용과 로컬 DB 정보를 별도로 두고, 설정해줬던 방법처럼
application-test.properties 파일을 만들고 경로 지정하려고 하며 검색해보니, 스택오버플로우에 좋은 답변이 있다.
test에서는 굳이 파일명을 다르게 할 필요가 없이, 경로를 main, test 위치만 다르게 하여서 @PropertySource("classpath:application.properties ")로 경로를 알려주는 방법이 있었다.
public class UserDaoTest {
UserDao dao;
@Before
public void setUp() {
dao = new UserDao();
DataSource dataSource = new SingleConnectionDataSource("jdbc:mysql://localhost/testdb", "spring", "book", true);
dao.setDataSource(dataSource);
}
}
@Autowired를 하지 않아도 되고, 직접 오브젝트 생성, 관계 설정을 해준다.
Autowired는 하나만 주입 시에는 생략해도, 필드 주입이 가능하고,,,
@Before 어노테이션으로 무조건 해당 메소드가 실행되니까 메소드 내부에서 생성을 해주는 방법이 가능한 것 같다.