EJB 3.1 Embeddable API + Junit 技術心得整理

在 Junit 中使用 Embedded GlassFish Server 做爲 EJB 元件的測試環境。The EJB 3.1 Embeddable API is designed for unit testing of EJB modules.

參考範例 Using the Embedded EJB Container to Test Enterprise Applications

設定

預設行爲

  • Embedded EJB Container 會複製 Glassfish Domain 下的 domain.xml 做爲他的 Domain 設定.
  • Embedded EJB Container 會在使用者目錄 下建立暫時的 domain, 例如: C:/Users/user/AppData/Local/Temp/domain6466380673056850xml。

啓動設定

Embedded EJB Container 啓動時,可進行設定以下的 Property [1]:

  • Installation location: Embedded EBJ Container 的安裝位置,預設為 GlassFish Server 的位置。
  • Instance location:Embedded EBJ Container instance 的安裝位置,依優先順序為: glassfish.embedded.tmpdir system property value, java.io.tmp system property value,as-install/domains/domain1
  • configuration.file:使用的設定檔,預設為 domain-dir/config/domain.xml。
  • Application Name:應用程式的名稱,會影響 EJB 元件的 JNDI 名稱。預設的 Application name 為 classes。類別的預設 JNDI 名稱為 jndi:global/classes/[you_class_name]。若 Application Name 設爲 App,則類別的預設名稱為 jndi:global/app/classes/[you_class_name]

as-install 是指 GlassFish Server 安裝的根目錄,内有 domains 及 lib 目錄。 domain-dir 是指 伺服器實體的根目錄,例如: C:\glassfish4\glassfish\domains

在 Log 檔的一開始會顯示 Embedded GlassFish Server 所使用的:installation location, configuration file. 也可以在 Log 檔中找到 EJB 元件的 JNDI 名稱。

Resources 的設定

  • 若要測試 Entity Bean,需手動啓動資料庫。
  • 和一般的 GlassFish Server 上的 Resources 設定相同。可使用 glassfish-resources.xml 來設定。或者,到 Glassfish 的 Admin Console 設定 jdbc resources。
  • 若 Resources 未設定好,執行測試時會出現錯誤訊息:

Jun 09, 2017 1:54:22 PM org.glassfish.deployment.admin.DeployCommand execute SEVERE: Exception while preparing the app : Invalid resource : { ResourceInfo : (jndiName=java:app/jdbc/TicketClasspm), (applicationName=classes) } com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : { ResourceInfo : (jndiName=java:app/jdbc/TicketClasspm), (applicationName=classes) }

  • 另外,若 persistence.xml 中的 Data Source 欄位設定錯誤,也會出現上述的訊息。注意,Data Source 欄位上的名字不用加上 java:app/ 前置字串。

如果確認 Resource 的設定無誤,但執行測試時仍然出現上述錯誤,試著重新部署應用程式,看是否能解決問題。

測試 EJB

若要在 junit 中測試 EJB,我們無法在 embedded glassfish 中使用 CDI 的功能,所以必須手動取得 EJB 的 instance。所需的步驟如下:

  1. 取得 EJBContainer 物件
  2. 使用 lookup 方法取得 EJB 的實體

底下是在 junit 的 @BeforeClass@AfterClass 的兩個方法下取得 EJB container 及 EJB 的實體:

@BeforeClass
    public static void setUpClass() throws Exception {
        // container is a static field for the test class 
        container = EJBContainer.createEJBContainer();
        System.out.println("Opening the container");

        ticketDataFacade = (TicketDataFacade) container.getContext().lookup("java:global/classes/TicketDataFacade");
        receiverFacade = (ReceiverFacade) container.getContext().lookup("java:global/classes/ReceiverFacade");
        ticketReserveTxnFacade = (TicketReserveTxnFacade) container.getContext().lookup("java:global/classes/TicketReserveTxnFacade");
        ticketPickUpMethodFacade = (TicketPickUpMethodFacade) container.getContext().lookup("java:global/classes/TicketPickUpMethodFacade");
    }

    @AfterClass
    public static void tearDownClass() {
        container.close();
        System.out.println("Closing the container");
    }

測試 Entity

測試 Entity 時,主要的問題是取得 EntityManager 實體。若在 EJB 中已有使用 @PersistentContext 注入 EntityManager 實體,在取得 EJB 時 embedded GlassFish 會自動幫我們注入。

但如果 embedded GlassFish 無法爲我們自動注入時,就必須手動的產生 EntityManager 實體及執行 DML 所需要的 Transaction。

例子如下:

// #1 Get the entity manager by using the EntityManagerFactory
EntityManagerFactory factory  Persistence.createEntityManagerFactoy("TicketCare-ProductionPU");
EntityManager em = factory.createEntityManager();
// Prepare the dml string
String del_str = "delete from TicketingEntity  where t.ticket = :ticket";
// #2 Create a EntityTransaction
EntityTransaction emTxn = em.getTransaction();
// #3 Begin the transaction
emTxn.begin();
for (Ticket ticket: tickets){
    em.createQuery(del_str).setParameter("ticket" ticket).executeUpdate();
}
// #4 commit to end the transaction
emTxn.commit();
// #5 close the EntityManager
em.close()
// #6 close the EntityManagerFactory
factory.close();

延伸閲讀

References

[1] Oracle, 2011, EJB 3.1 Embeddable API Properties in Oracle GlassFish Server 3.1 Embedded Server Guide. https://docs.oracle.com/cd/E18930_01/html/821-2424/gjlde.html. Accessed on 2017/06/10. [2] Oracle , 2013. GlassFish Server Open Source Edition Embedded Server Guide, Release 4.0. http://www.emse.fr/~lalevee/ismin/eb/documents/glassfish-docs/embedded-server-guide.pdf. Accessed on 2017/06/10

results matching ""

    No results matching ""