๐Ÿ’ฅ[@DataJpaTest] Error creating bean with name 'dataSource' ์—๋Ÿฌ

์ตœ์žฌํ˜ยท2022๋…„ 10์›” 21์ผ
1
post-thumbnail
post-custom-banner

๐Ÿ’ฅ๋ฌธ์ œ ์ƒํ™ฉ

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 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ํ…Œ์ŠคํŠธ ์‹œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๋งŒ ๋„์šฐ๋ฉด ๋˜๋‹ˆ ํ…Œ์ŠคํŠธ ์†๋„๊ฐ€ ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, 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์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๋ช…์‹œํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“šReference

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTest.html

https://wave1994.tistory.com/181

profile
์ž˜๋ชป๋œ ๊ณ ๋ฏผ์€ ์—†์Šต๋‹ˆ๋‹ค
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€