2016-12-16 15 views
0

Spring WebアプリケーションのトランザクションJUnitテストは失敗します。具体的にトランザクションSpringJUnit4テストの失敗

:私はMavenので、各テストを実行する場合は、別途、彼らが駆け抜ける:

mvn -Dtest=Test1 
mvn -Dtest=Test2 

私は

mvn -Dtest=Test1,Test2 

を実行すると、私は試験の一つでJPAのエラーが表示されます。

Could not open JPA EntityManager for transaction; nested exception is 
    java.lang.IllegalStateException: 
     Attempting to execute an operation on a closed EntityManagerFactory." 
     type="org.springframework.transaction.CannotCreateTransactionException" 
     org.springframework.transaction.CannotCreateTransactionException: 
      Could not open JPA EntityManager for transaction; nested exception is 
       java.lang.IllegalStateException: 
        Attempting to execute an operation on a closed EntityManagerFactory. 
         at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.verifyOpen(EntityManagerFactoryDelegate.java:338) 
         at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:303) 
         at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336) 
         at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302) 
         at org.springframework.orm.jpa.JpaTransactionManager.createEntityManagerForTransaction(JpaTransactionManager.java:449) 
         at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:369) 
         at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) 
         at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:439) 
         at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) 
         at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:64) 
         ... 

確信しているプラ​​グインを設定して各テストのJVM全体を再作成すると、非常識な時間がある。

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>${maven.surefire.version}</version> 
    <configuration> 
     <reuseForks>false</reuseForks> 
     <forkCount>1</forkCount> 
    </configuration> 
</plugin> 

アプリケーションのセットアップ:春Rooので

  • 春、
  • のEclipseLink JPAプロバイダのテスト・セットアップのための

applicationContext.xmlをとして(これproxymode = asjectJ!):

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" 
xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> 
<context:component-scan base-package="[packagename]"> 
    <context:exclude-filter expression=".*_Roo_.*" type="regex" /> 
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" /> 
</context:component-scan> 
<context:spring-configured /> 
<context:property-placeholder location="classpath*:META-INF/spring/*.properties" /> 
<context:annotation-config /> 

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
    id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

<tx:annotation-driven mode="aspectj" 
    transaction-manager="transactionManager" /> 

<bean 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="persistenceUnit" /> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 
<bean class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close" id="dataSource"> 
    <property name="driverClassName" value="${test_database.driverClassName}" /> 
    <property name="url" value="${test_database.url}" /> 
    <property name="username" value="${test_database.username}" /> 
    <property name="password" value="${test_database.password}" /> 
    <property name="testOnBorrow" value="true" /> 
    <property name="testOnReturn" value="true" /> 
    <property name="testWhileIdle" value="true" /> 
    <property name="timeBetweenEvictionRunsMillis" value="1800000" /> 
    <property name="numTestsPerEvictionRun" value="3" /> 
    <property name="minEvictableIdleTimeMillis" value="1800000" /> 
    <property name="validationQuery" value="SELECT 1" /> 
</bean> 

<jdbc:initialize-database data-source="dataSource" 
    ignore-failures="ALL"> 
    <jdbc:script location="${test_database.selectLocation}" /> 
    <jdbc:script location="${test_database.initLocation}" /> 
    <jdbc:script location="${test_database.dataLocation}" /> 
</jdbc:initialize-database> 
</beans> 

JUnitテストは、次のようになります。

@WebAppConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
    "classpath:META-INF/spring/applicationContext.xml", 
    "classpath:META-INF/spring/webmvc-config.xml" }) 
@TransactionConfiguration(transactionManager = "transactionManager") 
@DirtiesContext 
public class Test1 { 

    @Autowired 
    WebApplicationContext wac; 

    private MockMvc mockMvc; 

    @PersistenceContext 
    EntityManager entityManager; 

    @Before 
    public void setup() throws Exception { 
     this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); 
    } 

    @Test 
    @Transactional 
    public void getJSONTest() throws Exception { 
    ... 
    } 
} 

誰もがこれらのテストの2が接続されている方法任意のアイデアを持っていますか?エンティティマネージャを閉じなければなりませんが、理由と方法は?

ご迷惑をおかけして申し訳ありません。

EDIT1:提案されているように除去@TransactionConfigurationと@DirtiesContextが、今私はEDIT2

No transaction is currently active; nested exception is 
    javax.persistence.TransactionRequiredException 

を得る:私はこれまでのところ、私はテストの再生を実行するためにしたことを問題を突き止めホール。したがって、テストは互いに独立しているわけではありません。私は、異なるエラー/動作で毎回生じる注釈と実行命令のいくつかの置換を試みました。

は今のところ、クラスレベルの設定は次のとおりです。新しく初期化されたコンテキストは時々助けるように見えるので、

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
    "classpath:META-INF/spring/applicationContext.xml", 
    "classpath:META-INF/spring/webmvc-config.xml" }) 
@WebAppConfiguration 
@Transactional 
@DirtiesContext 

私は、再び@DirtiesContext注釈を入れました。

それはここで本当の問題を追跡するのは難しいですが、私は1つの具体的な質問に来た:

私は@Transactionalで私のテストクラスを包み、私の試験方法で、私は

mockMvc.perform(MockMvcRequestBuilders.post(...)) 

を呼び出し、呼び出しコントローラーメソッド。このコントローラメソッドは@Transactionalメソッドを持つ別のBeanに委譲します。 mockMvc.perform()が返った後、ユニットテスト天気をチェックして、値がデータベースに書き込まれています。私は、トランザクションがデータベースにコミットされている場合、または同じTransaction/entityManagerが使用されている場合にのみ、これが機能することを認識しています。テストメソッドのトランザクションは、呼び出されたコントローラのものと同じですか、ここでは2つの異なるentityManagers /トランザクションについて説明していますか?

答えて

0

私は@DirtiesContextはそれをやっていると言うだろう - ここhttp://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/annotation/DirtiesContext.html

を参照してください、私がしようとします:

  1. @TransactionConfiguration(トランザクションマネージャー= "のTransactionManager")を削除する - 私はそれが応じて必要はありません信じています
  2. あなたの春のXML設定に@DirtiesContext

を削除し、状況が改善されている場合してみてください... これは "のために私がテストDAO層に使用するセットアップ、

@RunWith(SpringRunner.class) 
@ContextConfiguration(classes = RealDbDAOTests.class) 
@Transactional 
@Rollback 
public class DaoTests { 
.... 
} 
+0

申し訳ありませんが(各メソッドは、実際に本物のデータベースに到達しますが、データベースを@Rollbackのおかげで、テストによって変更されることはありません、そのためのテストが互いに干渉していない)でありますJPAのエラーがなくなったことに気付いたが、今では「例外の説明:現在トランザクションはアクティブではない」というメッセージが表示されています。エラー:/ – hFonti

+0

ええと、そこに@Transactionalアノテーションがありますか?テストクラスのアノテーション設定がどのようになっているかをお知らせください。 –

関連する問題