2015-10-19 83 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 
}