
우테코에서 Spring 학습 테스트를 진행하다가 @SpringBootTest를 볼 수 있었다.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UpdatingDaoTest {
@Autowired
private UpdatingDAO updatingDAO;
@Autowired
private QueryingDAO queryingDAO;
@Autowired
private JdbcTemplate jdbcTemplate;
...
}
다른 테스트에는 @JDBCTest라는 어노테이션도 존재했다.
@JdbcTest
public class NamedParamTest {
private NamedParamDAO namedParamDAO;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
...
}
문득 호기심이 생겼다.
@SpringBootTest를 @JdbcTest로 바꾸면 동작하지 않을까?
예측하건데 두 테스트 모두 @Autowired를 통해 Bean을 주입하고 있다.
차이점은 DBConnection과 관련된 부분만 존재하는것이 아닐까? 라는 생각이 들었다.
위에서 @SpringBootTest로 작성된 코드를 @JdbcTest로 바꿔보았다.
@JdbcTest
public class UpdatingDaoTest {
@Autowired
private UpdatingDAO updatingDAO;
@Autowired
private QueryingDAO queryingDAO;
@Autowired
private JdbcTemplate jdbcTemplate;
...
}
테스트를 실행해보니 다음과 같은 에러가 발생했다.
Error creating bean with name 'nextstep.helloworld.jdbc.jdbctemplate.UpdatingDaoTest': Unsatisfied dependency expressed through field 'updatingDAO'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'nextstep.helloworld.jdbc.jdbctemplate.UpdatingDAO' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'nextstep.helloworld.jdbc.jdbctemplate.UpdatingDaoTest': Unsatisfied dependency expressed through field 'updatingDAO'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'nextstep.helloworld.jdbc.jdbctemplate.UpdatingDAO' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'nextstep.helloworld.jdbc.jdbctemplate.UpdatingDAO' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
주의깊게 볼 만한 내용으로는 UnsatisfiedDependencyException, NoSuchBeanDefinitionException이 발생했다는 부분이다.
에러메시지로 볼 수 있는 내용으로는 UpdatingDaoTest를 수행하는 과정에서 UpdatingDAO가 Bean으로 등록되지 않아 에러가 발생했다고 유추해볼 수 있겠다.
다음과 같은 과정을 통해 JdbcTest의 Bean 등록과정을 알아보고 싶어졌다.
@SpringBootTest를 @JdbcTest로 바꾸기만 했다. @SpringBootTest를 @JdbcTest이 Bean을 등록하는 과정이서 차이가 있을것이다.공식문서를 참고해서 살펴보자.
Annotation for a JDBC test that focuses only on JDBC-based components.
Using this annotation will disable full auto-configuration and instead apply only configuration relevant to JDBC tests.
By default, tests annotated with @JdbcTest are transactional and roll back at the end of each test. They also use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The @AutoConfigureTestDatabase annotation can be used to override these settings.
If you are looking to load your full application configuration, but use an embedded database, you should consider @SpringBootTest combined with @AutoConfigureTestDatabase rather than this annotation.
When using JUnit 4, this annotation should be used in combination with @RunWith(SpringRunner.class).
요약하자면 @JdbcTest를 사용하면 Jdbc 테스트와 관련된 설정만 적용된다고 한다.
큰 특징은 다음과 같다.
만약 내장형 DB를 사용하여 테스트하고자 한다면 @SpringBootTest를 고려하는 것이 좋다고 한다.
그렇다면 Spring DataSource는 무엇이길래 자동으로 등록될까?
스프링 부트는 기본적으로 DB URL이 명시되어 있으면 해당 URL로 Connection을 연결하고, URL이 명시되어 있지 않다면 내장 데이터베이스를 생성한다.
더 자세한 내용은 참고자료를 보는것을 추천합니다 :)
JdbcTest 어노테이션이 붙으면 URL이 명시되어있어도 in-memory DB를 사용한다.
DB 테스트를 진행할 때는 다른 Component들을 Bean으로 등록하는 과정이 필요없기 때문에 Bean으로 등록해야할 정보가 Jdbc와 관련된 정보 뿐이라면 @JdbcTest를 사용하도록 하자.
ex) JdbcTemplate, DataSource 등
좋은 글 감사합니다
덕분에 왜 @JdbcTest를 썼는데 @Repository로 등록한 빈들이 없다고 뜨는지 알 수 있었어요