2015-10-19 80 views
0

有沒有辦法訪問通常由容器創建並由容器管理的對象,該對象不是由容器創建或管理的類?換一種說法,當存在容器時,可以使用容器管理的類實例,而在沒有容器時使用常規的POJO。如何從不受容器管理的類訪問容器管理的對象

對我來說,關鍵是測試類不知道它所獲得的類是來自容器還是來自某個存根。

我可能是老派,但我想用一個可配置的工廠類訪問我的數據庫。在生產或集成測試中,它將返回一個容器注入我的DAL接口實現。單元測試時,我想將DAL存根並返回靜態值。

這可能嗎?

怎麼辦?

這是我在這麼遠,但仍然沒有喜悅哪裏...

工廠類

@Stateless 
public class DALFactory 
{ 
    @Inject 
    private static DALInterface DAL; 

    public static void init(String fqcn) 
    { 
     // use reflect to create unit test instance 
    } 

    public static DALInterface getDAL() 
    { 
     return DAL; 
    } 
} 

測試類

public class test 
{ 
    public void testDALAccess() 
    { 
     Table t = new Table(); // Instance of class representing a table 
     DALFactory.getDAL().persist(t); 
    } 
} 

時,我提供我的testDAL這只是正常因爲我用FQCN調用了init(),但是當我嘗試使用容器管理的實例時,它失敗了。

你大概可以猜到我對CDI和JPA有點新鮮。

僅供參考我將DALFactory標記爲@Stateless的唯一原因是它可以在有容器時由容器管理。

+0

你可能有一個錯誤的觀念,CDI的一個主要觀點是駕馭靜態屬性。 –

+0

另外,EJB和CDI是不同的技術,雖然非常相似。 '@Stateless'將該類標記爲EJB,但「@Inject」正在尋找CDI注入。如果這是行得通的,那很好,但是你可能會發現一些不合要求的行爲。 (如果你想保持一致,你應該使用'@ SessionScoped'而不是'@ Stateless',或'@ EJB'而不是'@Inject'。) – dcsohl

+0

@AnonyRaymond OK,那麼你如何注入一個測試存根實現單元測試的接口呢?我不希望在部署到不同的環境之前更改代碼,因爲我想從存根移動到完全實現...... – BigMac66

回答

0

所以這裏是我最終做的解決這個問題。在我做完這些之後,我能夠隔離取決於注入和相關容器的代碼,以便在沒有容器的情況下測試它。

注 - 我仍然對其他方式解決這個問題,以便我可以測試相同的代碼有和沒有容器執行注射。

// DAL廠

public class DALFactory 
{ 
    private static DALInterface DAL; 

    public static void setDAL(DALInterface di) 
    { 
     DAL = di; 
    } 

    public static void init(String fqcn) 
    { 
     // use reflect to create unit test instance 
    } 

    public static DALInterface getDAL() 
    { 
     return DAL; 
    } 
} 

//根注射類,這必須是可注射樹的頂部

@Stateless 
public MainClass 
{ 
    @Inject 
    ProdDAL dal; 

    @PostConstruct 
    public void postConstruct() 
    { 
     DALFactory.setDAL(new DALWrapper(this.dal)); 
    } 
} 

// DALWrapper

public DALWrapper implements DALInterface 
{ 
    private ProdDAL dal; 

    public DALWrapper(ProdDAL prodDAL) 
    { 
     this.dal = prodDal; 
    } 

... rest of interface goes here 
}