インメモリDBを起動してJPAエンティティをテストする方法は?

Mathew Alden:

私はJPAの経験があまりないので、自動テストを作成して、JPAエンティティーが取得するはずのレコードを取得していることを確認したいと思いました。私の計画は、テスト用にメモリ内H2 DBを起動し、それに対していくつかの簡単なCRUD操作を実行して、データが期待どおりに戻ってくることを確認することでした。

Spring Bootでインメモリデータベースを作成する方法がわかりません。これが私がこれまで持ってきたものですが、うまくいきません。

これは、JPAリポジトリを作成する構成です。これは適切なアプリケーションコードであり、現在、実際のOracle DBで動作しています。

@Configuration
@EnableJpaRepositories("com.name.project.webservice.dao")
@EntityScan("com.name.project.webservice.types")
public class JpaRepositoriesConfig {
    // Intentionally empty.
}

この構成をテストにインポートします。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {JpaRepositoriesConfig.class})
public class JpaEntityTest {

    @Test
    public void test(){}
}

次に、テスト固有のプロパティファイルを記述src/test/resources/application.propertiesして、アプリケーションのOracle構成をテストのH2構成に置き換えます。

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1

最後に、H2 jarをpomに追加します。このjarの存在は、私のテストの注釈とともに、Spring Bootに私のプロパティファイルに従ってH2データベースを起動するように指示する必要があります。

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

これで、すべてがセットアップされたはずです(またはそう思いました)。しかし、テストを実行すると、アプリコンテキストの起動に失敗し、次のスタックトレースが表示されます。

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facilityRepository': Cannot create inner bean '(inner bean)#11eadcba' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#11eadcba': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:361)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:131)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1681)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1433)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:826)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:119)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
    ... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#11eadcba': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:314)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:662)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:479)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:346)
    ... 43 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:771)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:303)
    ... 51 more

このエラーは私を驚かせた。Spring BootがentityManagerFactoryを自動的に提供するはずだと思っていました。私のアプリはentityManagerFactory Beanをインスタンス化することはなく、正常に動作します。

だから私に言っても構わないのなら、私はこれを正しく構成するために少なくとも正しい軌道に乗っていますか?このエラーを引き起こしているのを逃したステップは何ですか?entityManagerFactoryを手動で宣言する必要がありますか?

ご協力ありがとうございました。

編集:上に記録したテストのプロパティファイルとは対照的に、ここに私のアプリのプロパティファイルの関連部分があります。

spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url= <<database-url>>
spring.datasource.tomcat.max-active=5
spring.datasource.tomcat.initial-size=1
spring.datasource.tomcat.max-wait=20000 
spring.datasource.tomcat.max-idle=1
Mathew Alden:

Testクラスで次のアノテーションを使用することで、インメモリデータベースをSpringコンテキストに追加できました。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JpaRepositoriesConfig.class })
@DataJpaTest

もちろん、私のpomに必要な依存関係を含める:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

私がやっていることがベストプラクティスに違反しているかどうかをお知らせください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ドメイン駆動設計で多形エンティティを使用してドメインモデリングにアプローチする方法は?

分類Dev

自動インクリメントIDを使用してJPAのエンティティに別の変数を設定する方法

分類Dev

Criteria APIを使用して子エンティティのプロパティをホワイトリストに登録してJPAエンティティを選択するにはどうすればよいですか?

分類Dev

AndroidインストルメントテストKotlin(ActivityTestRule)でアクティビティの起動を停止する方法はありますか

分類Dev

Spring JPAリポジトリを使用して複数のフィールドでエンティティをフィルタリングする方法は?

分類Dev

自動インクリメントキーを使用してテーブル内の特定のエンティティを見つける方法は?(エンティティフレームワーク)

分類Dev

ラムダ式とlinqを使用して、EFを使用して別のエンティティモデルタイプのリストを含むエンティティモデルをデータベースに追加する方法

分類Dev

JPAエンティティメタモデルを生成する方法

分類Dev

インラインエディタを使用してDialogflowフルフィルメントでhttpリクエストをテストする方法

分類Dev

Where句を使用してエンティティタイプのリストを取得する方法

分類Dev

値のリストを使用してエンティティ プロパティを定義する方法

分類Dev

ドメインエンティティとしてJPAエンティティを使用するオニオンアーキテクチャ

分類Dev

CoreDataエンティティをポイントする方法は?

分類Dev

JPAで「エリアごとにエンティティをカウント」のリストを取得する方法

分類Dev

通知からアクティビティを起動してメインアクティビティに戻る

分類Dev

非常に不思議なループ動作:リストはアイデンティティを変更します。何が起こっている?

分類Dev

cronを使用してbashでインタラクティブシェルスクリプトを1時間ごとに起動する方法は?

分類Dev

Spring BootでLombokを使用してJPAエンティティのBuilder()にアクセスする方法は?

分類Dev

jpaを使用してエンティティを編集する

分類Dev

エスプレッソを使用した起動アクティビティインテントのテスト

分類Dev

SpringBoot + Hibernate JPA Lazy fetchingモードでもエンティティのリストをクエリする

分類Dev

EXTRACTステートメントoracleを使用してクエリをフィルタリングする方法

分類Dev

リモートメソッド呼び出しによってフェッチされたHibernateエンティティを初期化する方法は?

分類Dev

カスタム認証とインメモリホスティングを使用してASP.NETWebAPI統合テストを実行する方法

分類Dev

Spring BootとJPAを使用してGETリクエストで1対多のエンティティをすべて取得する方法

分類Dev

Spring BootとJPAを使用してGETリクエストで1対多のエンティティをすべて取得する方法

分類Dev

Entity Frameworkのコンテキストに対してエンティティを検証する方法は?

分類Dev

メインエンティティからIDを取得し、normalizrでネストされたエンティティにラップする方法

分類Dev

リストエンティティを使用してメッセージを印刷する正しい方法はありますか?

Related 関連記事

  1. 1

    ドメイン駆動設計で多形エンティティを使用してドメインモデリングにアプローチする方法は?

  2. 2

    自動インクリメントIDを使用してJPAのエンティティに別の変数を設定する方法

  3. 3

    Criteria APIを使用して子エンティティのプロパティをホワイトリストに登録してJPAエンティティを選択するにはどうすればよいですか?

  4. 4

    AndroidインストルメントテストKotlin(ActivityTestRule)でアクティビティの起動を停止する方法はありますか

  5. 5

    Spring JPAリポジトリを使用して複数のフィールドでエンティティをフィルタリングする方法は?

  6. 6

    自動インクリメントキーを使用してテーブル内の特定のエンティティを見つける方法は?(エンティティフレームワーク)

  7. 7

    ラムダ式とlinqを使用して、EFを使用して別のエンティティモデルタイプのリストを含むエンティティモデルをデータベースに追加する方法

  8. 8

    JPAエンティティメタモデルを生成する方法

  9. 9

    インラインエディタを使用してDialogflowフルフィルメントでhttpリクエストをテストする方法

  10. 10

    Where句を使用してエンティティタイプのリストを取得する方法

  11. 11

    値のリストを使用してエンティティ プロパティを定義する方法

  12. 12

    ドメインエンティティとしてJPAエンティティを使用するオニオンアーキテクチャ

  13. 13

    CoreDataエンティティをポイントする方法は?

  14. 14

    JPAで「エリアごとにエンティティをカウント」のリストを取得する方法

  15. 15

    通知からアクティビティを起動してメインアクティビティに戻る

  16. 16

    非常に不思議なループ動作:リストはアイデンティティを変更します。何が起こっている?

  17. 17

    cronを使用してbashでインタラクティブシェルスクリプトを1時間ごとに起動する方法は?

  18. 18

    Spring BootでLombokを使用してJPAエンティティのBuilder()にアクセスする方法は?

  19. 19

    jpaを使用してエンティティを編集する

  20. 20

    エスプレッソを使用した起動アクティビティインテントのテスト

  21. 21

    SpringBoot + Hibernate JPA Lazy fetchingモードでもエンティティのリストをクエリする

  22. 22

    EXTRACTステートメントoracleを使用してクエリをフィルタリングする方法

  23. 23

    リモートメソッド呼び出しによってフェッチされたHibernateエンティティを初期化する方法は?

  24. 24

    カスタム認証とインメモリホスティングを使用してASP.NETWebAPI統合テストを実行する方法

  25. 25

    Spring BootとJPAを使用してGETリクエストで1対多のエンティティをすべて取得する方法

  26. 26

    Spring BootとJPAを使用してGETリクエストで1対多のエンティティをすべて取得する方法

  27. 27

    Entity Frameworkのコンテキストに対してエンティティを検証する方法は?

  28. 28

    メインエンティティからIDを取得し、normalizrでネストされたエンティティにラップする方法

  29. 29

    リストエンティティを使用してメッセージを印刷する正しい方法はありますか?

ホットタグ

アーカイブ