1

別のものが注入されている EJB をテストしようとしています。テスト目的で、注入された EJB にスタブを使用したいと考えています。テスト用の EJB のフレームワークとして openEJB を使用しました。

EJB は次のとおりです。

@Stateless
@Local(IService.class)
public class Service implements IService {

    @EJB
    private IBean bean;

    @Override
    public String doService(String data) {
        return bean.process(data);
    }
}

実際に注入された EJB :

@Stateless
@Local(IBean.class)
public class Bean implements IBean {

    private static Logger logger = Logger.getLogger(Bean.class);

    @Override
    public String process(String data) {
        logger.info("Bean processing : " + data);
        return "Bean processing : " + data;
    }
}

EJB のスタブ バージョン:

@Stateless
@Local(IBean.class)
public class BeanStub implements IBean {

    private static Logger logger = Logger.getLogger(BeanStub.class);

    @Override
    public String process(String data) {
        logger.info("Stub processing : " + data);
        return "Stub processing : " + data;
    }
}

そして使用されたJUnitテスト:

public class ServiceTest {

    private static Logger logger = Logger.getLogger(ServiceTest.class);

    private static InitialContext context;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // openEJB
        Properties p = new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
        p.put("openejb.altdd.prefix", "stub"); // use specific ejb-jar
        p.put("openejb.descriptors.output", "true");

        context = new InitialContext(p);
    }

    @Test
    public void testServiceStub() {
        try {
            IService service = (IService) context.lookup("ServiceStubLocal");
            assertNotNull(service);
            String msg = service.doService("service");
            assertEquals("Stub processing : service", msg);
        } catch (NamingException e) {
            logger.error(e);
            fail(e.getMessage());
        }
    }
}

特定の ejb-jar を使用して、実際の EJB の使用をスタブ 1 でオーバーライドしようとしました (サービスでデフォルトの「Bean」の代わりに「BeanStub」を使用したい)。

 <ejb-jar>
    <enterprise-beans>
    <session id="ServiceStub">
        <ejb-name>ServiceStub</ejb-name>
        <ejb-class>tests.Service</ejb-class>
        <ejb-local-ref>
            <ejb-ref-name>tests.Service/bean</ejb-ref-name>
            <ejb-link>BeanStub</ejb-link>
        </ejb-local-ref>
    </session>          
    </enterprise-beans>
</ejb-jar> 

残念ながら、EJB が宣言されているという問題があります。

    Apache OpenEJB 3.1.4 ビルド: 20101112-03:32
http://openejb.apache.org/
17:14:29,225 INFO 起動:70 - openejb.home = D:\Workspace_Java\tests\testejb
17:14:29,225 INFO 起動:70 - openejb.base = D:\Workspace_Java\tests\testejb
17:14:29,350 INFO config:70 - サービスを構成しています (id=デフォルト セキュリティ サービス、タイプ=SecurityService、プロバイダ-id=デフォルト セキュリティ サービス)
17:14:29,350 INFO config:70 - サービスの構成 (id=Default Transaction Manager、type=TransactionManager、provider-id=Default Transaction Manager)
17:14:29,381 INFO config:70 - クラスパスに EjbModule が見つかりました: D:\Workspace_Java\tests\testejb\target\test-classes
17:14:29,412 INFO config:70 - クラスパスに EjbModule が見つかりました: D:\Workspace_Java\tests\testejb\target\classes
17:14:29,428 INFO config:70 - ロードの開始: D:\Workspace_Java\tests\testejb\target\test-classes
17:14:29,428 INFO config:70 - AltDD ejb-jar.xml -> ファイル:/D:/Workspace_Java/tests/testejb/target/test-classes/META-INF/stub.ejb-jar.xml
17:14:29,850 INFO config:70 - ロードの開始: D:\Workspace_Java\tests\testejb\target\classes
17:14:29,850 INFO config:70 - AltDD ejb-jar.xml -> ファイル:/D:/Workspace_Java/tests/testejb/target/classes/META-INF/stub.ejb-jar.xml
17:14:29,850 INFO config:70 - エンタープライズ アプリケーションの構成: classpath.ear
17:14:29,912 INFO config:70 - サービスの構成 (id=デフォルト ステートレス コンテナー、タイプ=コンテナー、プロバイダー-id=デフォルト ステートレス コンテナー)
17:14:29,912 INFO config:70 - Bean ServiceStub のコンテナーの自動作成: コンテナー (type=STATELESS、id=Default Stateless Container)
17:14:29,912 情報オプション:70 - 「openejb.descriptors.output=true」を使用しています
17:14:29,912 情報オプション:70 - 「openejb.descriptors.output=true」を使用しています
17:14:29,928 INFO config:70 - 生成された ejb-jar.xml を C:\TEMP\ejb-jar-6391test-classes.xml にダンプします
17:14:29,959 INFO config:70 - 生成された openejb-jar.xml を C:\TEMP\openejb-jar-6392test-classes.xml にダンプします
17:14:29,959 情報オプション:70 - 「openejb.descriptors.output=true」を使用しています
17:14:29,959 INFO config:70 - 生成された ejb-jar.xml を C:\TEMP\ejb-jar-6393classes.xml にダンプします
17:14:29,975 INFO config:70 - 生成された openejb-jar.xml を C:\TEMP\openejb-jar-6394classes.xml にダンプします
17:14:30,006 INFO config:70 - エンタープライズ アプリケーション「classpath.ear」がロードされました。
17:14:30,084 INFO 起動:70 - アプリのアセンブル: classpath.ear
17:14:30,131 INFO 起動:70 - Jndi(name=ServiceStubLocal) --> Ejb(deployment-id=ServiceStub)
17:14:30,131 ERROR startup:46 - Jndi 名をバインドできませんでした。別の ejb によって取得される可能性があります。Jndi(name=openejb/Deployment/ServiceStub/tests.IService!Local)
17:14:30,131 INFO startup:70 - アンデプロイ アプリ: classpath.ear
17:14:30,147 ERROR startup:50 - アプリケーションをデプロイできませんでした: classpath.ear
org.apache.openejb.OpenEJBException: アプリケーションの作成に失敗しました: classpath.ear: デプロイ ServiceStub のビジネス ローカル インターフェイスをバインドできません
    org.apache.openejb.assemblyr.classic.Assembler.createApplication (Assembler.java:679) で
    org.apache.openejb.assemblyr.classic.Assembler.createApplication (Assembler.java:450) で

アプローチや ejb-jar の書き方に何か問題がありますか?

4

2 に答える 2

1

OpenEJB でも同様の問題とハードルがありました。テストのためにスタブ化とモック化が必要な場合 (そうでない人) は、私が最終的にそれを処理することができた人を見てください (OpenEJB の共同創設者である David からの大きな助けを得て)。最新バージョン (3.1.4) では、OpenEJB は Arquillian とほとんど同じように機能し、ejb-jar.xml とクラスパス スキャンなしで内部クラス テスト ドライバーを使用できます。

ここでハードルについて説明しました: http://jakub.marchwicki.pl/posts/2011/07/01/testing-ejb-application-openejb-without-classpath-scanning/。見てください、多分それはあなたのテストをより簡単にするでしょう.

于 2011-07-02T21:39:55.770 に答える
0

EasyMock や Mockito などのモック フレームワークを使用して、これをテストしてみませんか。デプロイメント記述子、EJB コンテナー、JNDI ルックアップなどは必要ありません。次のようなコードのみ:

@Test
public void testDoService() {
    IBean mockBean = EasyMock.createMock(IBean.class);
    mockBean.process("data");
    EasyMock.replay(mockBean);

    Service serviceToTest = new Service(mockBean);
    serviceTotest.doService("data");
    EasyMock.verify(mockBean);
}

そして、それは確かにずっと速く走るでしょう。

于 2011-03-11T16:32:28.587 に答える