2

persistence.xml で JTA トランザクションを指定した JPA アプリケーションがあります。なんらかの理由で、JTA を使用する場合、persistence.xml 内で JNDI データ ソースも指定する必要があることがわかりました。コンテナの外部で統合テストを行おうとしていて、JNDI が使用できない場合を除き、これで問題ありません。

私の質問は次のとおりです。

a) jdbc データソースを JTA トランザクション マネージャに挿入する方法はありますか? b) そうでない場合、統合テスト中に JNDI ルックアップをどのように処理しますか?

編集:統合テストを起動するときに発生するエラーは次のとおりです。

 Caused by: org.springframework.......DataSourceLookupFailureException:
 Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/myAppDataSource';
 nested exception is javax.naming.NoInitialContextException: Need to specify
 class name in environment or system property, or as an applet parameter,
 or in an application resource file:  java.naming.factory.initial
4

2 に答える 2

1

私自身も同様の問題に遭遇しました。SpringをJPAで使用しており、データベースをJNDI名として指定しています。最終的に、Mockitoを使用してJNDIをモックアウトすることにしました。これはとても簡単でした。これが私がそれをした方法です:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-config.xml"})
public class MyTestClass {

    private static final InitialContextFactoryBuilder contextFactoryBuilder = mock(InitialContextFactoryBuilder.class);
    private static final InitialContextFactory contextFactory = mock(InitialContextFactory.class);
    private static final Context context = mock(Context.class);
    private static final NameParser parser = mock(NameParser.class);
    private static final Name dbName = mock(Name.class);
    // This is the Datasource implementation from the H2 database
    private static final JdbcDataSource temporaryDbForTesting = new JdbcDataSource();

    @BeforeClass
    public static void setupMockJndi() throws NamingException {
        NamingManager.setInitialContextFactoryBuilder(contextFactoryBuilder);
        when(contextFactoryBuilder.createInitialContextFactory(any(Hashtable.class))).thenReturn(contextFactory);
        when(contextFactory.getInitialContext(any(Hashtable.class))).thenReturn(context);
        when(context.getNameParser(any(String.class))).thenReturn(parser);
        when(parser.parse("GatewayDbDataSource")).thenReturn(dbName);
        when(context.lookup(dbName)).thenReturn(temporaryDbForTesting);

        temporaryDbForTesting.setURL("jdbc:h2:~/test2");
        temporaryDbForTesting.setUser("sa");
        temporaryDbForTesting.setPassword("");
    }

    @Autowired
    private org.zzz.DomainObject toTest;

    @Test
    public void testPasswordChecking() {
        assertNotNull("There wasn't an object to test. Spring is broken!", toTest);
        // ... assertions and such ...
    }

}
于 2012-07-09T20:18:55.407 に答える
1

私はこれを自分で実験しませんでしたが、スタンドアロンのトランザクション マネージャーと XA 準拠のデータソースで実行可能です。Spring 2.5 では、ほとんどのサンプルが JOTM と XAPool を使用しJotmFactoryBeanています。しかし、これらは Spring 3.0 ではサポートされなくなり、Atomikosが「代替」のようです (スタンドアロンのトランザクション マネージャーと XA データソースを提供します)。以下にいくつかの構成サンプルを追加しました。

別の方法は、コンテナ内テストを実行することです ( GlassFish v3 Embeddedなどの組み込み Java EE コンテナまたはCargoなどの API を使用)。

資力

于 2010-06-10T00:04:14.793 に答える