如何从不受容器管理的类访问容器管理的对象
问题描述:
有没有办法访问通常由容器创建并由容器管理的对象,该对象不是由容器创建或管理的类?换一种说法,当存在容器时,可以使用容器管理的类实例,而在没有容器时使用常规的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
的唯一原因是它可以在有容器时由容器管理。
答
所以这里是我最终做的解决这个问题。在我做完这些之后,我能够隔离取决于注入和相关容器的代码,以便在没有容器的情况下测试它。
注 - 我仍然对其他方式解决这个问题,以便我可以测试相同的代码有和没有容器执行注射。
// 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
}
你可能有一个错误的观念,CDI的一个主要观点是驾驭静态属性。 –
另外,EJB和CDI是不同的技术,虽然非常相似。 '@Stateless'将该类标记为EJB,但“@Inject”正在寻找CDI注入。如果这是行得通的,那很好,但是你可能会发现一些不合要求的行为。 (如果你想保持一致,你应该使用'@ SessionScoped'而不是'@ Stateless',或'@ EJB'而不是'@Inject'。) – dcsohl
@AnonyRaymond OK,那么你如何注入一个测试存根实现单元测试的接口呢?我不希望在部署到不同的环境之前更改代码,因为我想从存根移动到完全实现...... – BigMac66