@Before annotation을 사용해서 모든 메서드에 미리 데이터베이스에 대한 정보를 넣었었다.
하지만 여기서의 문제는 애플리케이션 컨텍스트가 계속 초기화된다.
애플리케이션 컨텍스트가 만들어질 때는 모든 싱글톤 빈 오브젝트를 초기화하기 때문에 테스트에 많은 비용이 소모될 수 있다.
테스트마다 로그를 찍어보니

모든 다른 애플리케이션 오브젝트로 생성이 되고, 거기서 생긴 UserDao도 싱글톤이라고 하기에는 다른 인스턴스인 것을 볼 수 있다.
그렇기에 테스트마다 애플리케이션 컨텍스트를 생성하는 방법이 아닌, 스프링에서 직접 제공하는 애플리케이션 컨텍스트 테스트 지원 기능을 사용하는 것이 더 좋다고 한다.
package seungkyu;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
class UserDaoTest {
private UserDao userDao;
@Autowired
private ApplicationContext applicationContext;
@BeforeEach
public void setUp() throws SQLException, ClassNotFoundException {
this.userDao = applicationContext.getBean("userDao", UserDao.class);
userDao.deleteAll();
}
}
이렇게 수정해주었다.
applicationContext.xml에서 빈의 정보를 읽어서 주입해달라는 코드이다.

그렇게 만든 애플리케이션 오브젝트와 빈은 모두 싱글톤으로 하나만 만들어서 사용하는 것을 볼 수 있다.
이렇게 해서 하나의 테스트 클래스 내의 테스트 메서드는 같은 애플리케이션 컨텍스트를 공유해서 사용할 수 있음을 확인했다.
만약 다른 테스트까리 하나의 설정파일을 읽어와서 테스트를 진행한다면, 해당 테스트는 애플리케이션 컨텍스트를 하나만 만들어서 공유하도록 해준다.
이 덕분에 애플리케이션 컨텍스트를 하나만 만들 수 있게 되어 테스트의 속도가 대폭 빨라진다.
그리고 여기서 주입을 위해 @Autowired를 사용했는데, 간단하게 말하자면 @Autowired가 붙은 인스턴스 변수가 있으면 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내의 빈을 찾는다. 그리고 타입이 일치한다면 인스턴스 변수에 주입해준다. setter와 생성자가 없어도 스프링이 리플랙션을 통해 주입해준다고 한다. 만약 같은 타입이 2개 이상이라면 변수의 이름과 같은 이름의 빈이 있는지 확인한 후 있다면 주입한다.
@Autowired
private ApplicationContext applicationContext;
그리고 해당 코드를 보면 알겠지만, applicationContext 또한 자기 자신을 빈으로 등록한다.
이제 테스트를 진행해볼텐데, 이걸 실제 데이터베이스에 연결하면 안된다는 것을 알것이다.
만약 실제 데이터베이스에 연결하고 deleteAll을 해버린다면, 모든 사용자의 정보가 삭제되기 때문이다.
그렇기에 테스트를 위한 별도의 데이터베이스를 설정해야 한다.
지금 작성한 applicationContext.xml 말고, test-applicationContext.xml을 만들어서 테스트 환경에서만 해당 설정을 사용하도록 해보자.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource"
class = "org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="1204"/>
</bean>
<bean id="userDao" class="seungkyu.UserDao">
<constructor-arg ref="dataSource" />
</bean>
</beans>
이렇게 스키마를 변경하고
UserDaoTest의 ContextConfiguration을 다음과 같이 변경한다.
@ContextConfiguration(locations = {"/test-applicationContext.xml"})
해당 스키마를 사용하는지 확인해보기 위해, @AfterEach로 데이터를 남기며 테스트해보았다.

이렇게 테스트 데이터베이스를 사용해 테스트를 진행하는 것을 볼 수 있다.
테스트를 진행하면서 별도의 테스트 데이터베이스를 통해 더 완벽하게 테스트를 진행하도록 해야겠다.
'백엔드 > 토비의 스프링' 카테고리의 다른 글
[토비의 스프링] 3.1 다시 보는 초난감 DAO (0) | 2025.05.21 |
---|---|
[토비의 스프링] 2.5 학습 테스트로 배우는 스프링 (0) | 2025.05.20 |
[토비의 스프링] 2.3 개발자를 위한 테스팅 프레임워크 JUnit (0) | 2025.05.19 |
[토비의 스프링] 2.2 UserDaoTest 개선 (0) | 2025.05.18 |
[토비의 스프링] 2.1 UserDaoTest 다시 보기 (0) | 2025.05.17 |