Repository
๋จ์ ํ
์คํธ๋ฅผ ์์ฑํ๊ธฐ ์ํด, @DataJpaTest
์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ ค๊ณ ํ์ต๋๋ค. ์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก MariaDB๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
@DataJpaTest
JPA ํ ์คํธ ์, JPA ์ปดํฌ๋ํธ๋ค๋ง์ ๋์์ผ๋ก ํ ์คํธ๋ฅผ ์งํํ ์ ์๋๋ก ์ง์ํ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก
@Transactional
์ด๋ ธํ ์ด์ ์ด ํฌํจ๋์ด ์์ด ํ ์คํธ๊ฐ ์ข ๋ฃ๋๋ฉด ๋กค๋ฐฑ์ ์งํํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์คํธ ๋ด์ฉ์ ๋ฐ์ํ์ง ์์ต๋๋ค.
ํ ์คํธ๋ฅผ ์งํํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค. ๊ฐ๋จํ๊ฒ User ๋ก๊ทธ์ธ ์์ด๋๋ก ์ ์ ๋ฅผ ์กฐํํ๋ ํ ์คํธ์ ๋๋ค.
@DataJpaTest
class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Test
void findUserByUserLoginId() {
String userLoginId = "hello";
User user = User.builder()
.userLoginId(userLoginId)
.build();
userRepository.save(user);
User findUser = userRepository.findUserByUserLoginId(userLoginId).get();
assertThat(findUser).isEqualTo(user);
assertThat(findUser.getUserLoginId()).isEqualTo("hello");
}
}
๊ทธ๋ฐ๋ฐ ํ ์คํธ๋ฅผ ์งํํ๋๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์๋ฌ์ ๋ด์ฉ์ ์ฝ์ด๋ณด๋, ๋ค์๊ณผ ๊ฐ์ ๊ตฌ๋ฌธ์ด ์์์ต๋๋ค.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoConfigureTestDatabase.
dataSource
๋ฅผ ํ
์คํธ๋ฅผ ์ํ ๋ด์ฅ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๊ต์ฒดํ์ง ๋ชปํ๋ค๋ ๋ด์ฉ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๋ง์ฝ ๋ด์ฅ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๊ต์ฒดํ๋ ค๋ฉด, @AutoConfigureTestDatabase
์ด๋
ธํ
์ด์
์ replace ์์ฑ์ ๊ณ ์ณ๋ณด๋ผ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@AutoConfigureTestDatabase
์ด๋
ธํ
์ด์
์ ์ดํด๋ณด๊ธฐ ์ด์ ์, @DataJpaTest
์ด๋
ธํ
์ด์
์ค๋ช
์ ์ฝ์ด๋ณด๋ฉด,
@DataJpaTest
๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ ํ
์คํธ๋ง๋ค ๋กค๋ฐฑ์ ์งํํ๊ณ , ํ
์คํธ์๋ ๋ด์ฅ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ ๋ ์ธ๋ถ์ MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํด์ ์๋ฌ๊ฐ ๋ฐ์ํ ๋ชจ์์
๋๋ค. ๋ ์ฝ์ด๋ณด๋ฉด, @AutoConfigureTestDatabase
์ด๋
ธํ
์ด์
์์ ์ด๋ฌํ ์ค์ ์ ๋ณ๊ฒฝํ ์ ์๋ค๊ณ ํฉ๋๋ค. ๊ทธ๋ฌ๋๊น ์๋ฌ ๋ฉ์ธ์ง์์ @AutoConfigureTestDatabase
์ด๋
ธํ
์ด์
์ ํ์ธํ๋ผ๊ณ ํ๋๊ฐ ๋ณด๋ค์.
@AutoConfigureTestDatabase
์ด๋
ธํ
์ด์
์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public @interface AutoConfigureTestDatabase {
/**
* Determines what type of existing DataSource bean can be replaced.
* @return the type of existing DataSource to replace
*/
@PropertyMapping(skip = SkipPropertyMapping.ON_DEFAULT_VALUE)
Replace replace() default Replace.ANY;
/**
* The type of connection to be established when {@link #replace() replacing} the
* DataSource. By default will attempt to detect the connection based on the
* classpath.
* @return the type of connection to use
*/
EmbeddedDatabaseConnection connection() default EmbeddedDatabaseConnection.NONE;
/**
* What the test database can replace.
*/
enum Replace {
/**
* Replace the DataSource bean whether it was auto-configured or manually defined.
*/
ANY,
/**
* Only replace the DataSource if it was auto-configured.
*/
AUTO_CONFIGURED,
/**
* Don't replace the application default DataSource.
*/
NONE
}
์๋ฌ๋ฉ์ธ์ง๊ฐ ์๋ ค์ค ๋๋ก Replace๋ฅผ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. Enum ํ์
์ด๊ณ , ๊ฐ์ผ๋ก๋ ANY
, AUTO_CONFIGURED
, NONE
์ด ์๋ค์. ๋ํดํธ๊ฐ์ ANY
๋ก ์ค์ ๋์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฃผ์์ ์ ํ ์ค๋ช ์ ์ฝ์ด๋ณด๊ฒ ์ต๋๋ค.
- ANY
- ์๋ ๊ตฌ์ฑ, ์๋ ๊ตฌ์ฑ๋ DataSource ๋น ๋ชจ๋ ๊ต์ฒดํจ
- AUTO_CONFIGURED
- ์๋ ๊ตฌ์ฑ๋ DataSource ๋น๋ง ๊ต์ฒดํจ
- NONE
- ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ค์ ๋ DataSource๋ฅผ ๊ต์ฒดํ์ง ์์
์ค๋ช
์ ๋ณด๋, @DataJpaTest
๋ฅผ ์ด์ฉํ์ฌ ํ
์คํธ ์คํ ์, ๋ด์ฅ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๊ต์ฒดํ ์ง ๋ง์ง์ ๊ธฐ์ค์ ์ ์ํด์ฃผ๋ ๊ฐ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฌธ์ ์ ์์ธ์ ์ฌ๊ธฐ์ ์์์ต๋๋ค. ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ค์ ๋ Replace.ANY
์์ฑ์ผ๋ก ์ธํด, ๊ธฐ์กด์ ์ ๊ฐ ์ฌ์ฉํ๋ MariaDB dataSource๋ฅผ ๋ฑ๋ก๋์ง ์์ in-memory dataSource๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํ๋ ค๋ค ๋ณด๋, "Error creating bean with name 'dataSource'" ์๋ฌ ๋ฉ์ธ์ง๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด์์ต๋๋ค.
์ ์์ฑ ๊ฐ์ ๋ณ๊ฒฝํด์ฃผ๋ฉด ํด๊ฒฐ์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด ๋ถ๋ถ์ ๊ฐ๋ฐ์์ ์ ํ์ ๋ฌ๋ฆฐ ๊ฒ ๊ฐ์ต๋๋ค.
๋ง์ฝ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ํ ์คํธ ์ ์ดํ๋ฆฌ์ผ์ด์ ๋ง ๋์ฐ๋ฉด ๋๋ ํ ์คํธ ์๋๊ฐ ๋น ๋ฅด๊ณ ๊ฐํธํ๋ค๋ ์ฅ์ ์ด ์๊ฒ ์ต๋๋ค. ํ์ง๋ง, in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด, ์๋ก์ด DataSource๋ฅผ ๋ฑ๋กํด์ผ ํ๋ ์๊ณ ๊ฐ ์๊ณ , ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ง๋ค ๋ฐฉ์ธ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ (์ฝ๊ฐ์ Query๋ฌธ์ ์ฐจ์ด๊ฐ ์์ ์ ์์ต๋๋ค.) ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํด์ ์ด์๋๋ ์๋ฒ์ ํ ์คํธ ๊ฒฐ๊ณผ๊ฐ๊ณผ๋ ๋ค๋ฅผ ์๋ ์์ต๋๋ค.
๊ฐ๋ฐ ๋จ๊ณ์์๋ ๊ฐํธํ๊ฒ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋, ํตํฉ ํ ์คํธ ์ ์ ์ค์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ํ ์คํธ๋ฅผ ํด๋ณด๋ ๋ฑ์ ๋ฐฉ๋ฒ์ด ์์ ๊ฒ ๊ฐ์ต๋๋ค.
@DataJpaTest
์์ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ฌ์ฉํ ์ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ํ์๋H2
,DERBY
,HSQLDB
๊ฐ ์์ต๋๋ค.
@AutoConfigureTestDatabase
์ด๋ ธํ ์ด์ ์์ connect() ๋ฉ์๋ ๋ฐํ๊ฐ์ผ๋ก ์ ๊ณตํ๋ EmbeddedDatabaseConnection ์์ ํ์ธํ ์ ์์ต๋๋ค.public enum EmbeddedDatabaseConnection { /** * No Connection. */ NONE(null, null, null, (url) -> false), /** * H2 Database Connection. */ H2(EmbeddedDatabaseType.H2, DatabaseDriver.H2.getDriverClassName(), "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", (url) -> url.contains(":h2:mem")), /** * Derby Database Connection. */ DERBY(EmbeddedDatabaseType.DERBY, DatabaseDriver.DERBY.getDriverClassName(), "jdbc:derby:memory:%s;create=true", (url) -> true), /** * HSQL Database Connection. * @since 2.4.0 */ HSQLDB(EmbeddedDatabaseType.HSQL, DatabaseDriver.HSQLDB.getDriverClassName(), "org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:%s", (url) -> url.contains(":hsqldb:mem:"));
๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ค์ ๋ AutoConfigureTestDatabase.Replcae.ANY
์์ฑ์ด ๋ฑ๋ก๋์ง ์์ in-memory ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์คํ๋ง ์ปจํ
์ด๋์์ ๊บผ๋ด๋ ค๋ ๊ฒ์ด ๋ฌธ์ ์ธ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค.
๊ธฐ์กด์ ์ฌ์ฉํ๋ MariaDB๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ ค๋ฉด, dataSource๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ฒ ๋ค๋ ๊ฒ์ ๋ช ์ํ๋ฉด ํด๊ฒฐ์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
ํด๊ฒฐํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Test
void findUserByUserLoginId() {
String userLoginId = "hello";
User user = User.builder()
.userLoginId(userLoginId)
.build();
userRepository.save(user);
User findUser = userRepository.findUserByUserLoginId(userLoginId).get();
assertThat(findUser).isEqualTo(user);
assertThat(findUser.getUserLoginId()).isEqualTo("hello");
}
}
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
์ด๋
ธํ
์ด์
์ ํตํด, Replace ์ ๋ต์ NONE์ผ๋ก ์ฌ์ฉํ ๊ฒ์ ๋ช
์ํ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ํ ์คํธ๊ฐ ์ฑ๊ณตํ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.