关于在使用junit通过其原始POJO API对(EJB 3.0)EJB进行集成测试期间注入备用数据源的快速问题。
我一直在将原始POJO服务转换为EJB3会话bean。这样做实际上只是意味着直接注释POJO。这些服务还附带现有的junit集成测试(检查查询真实测试数据库的方法的结果)。
其中一些服务需要直接的java.sql.Connection,所以我打算通过注入的DataSource来配置它。这样做的目的是我可以将bean直接部署到app服务器(WLS,因为它发生)。但是,我还希望现有的集成测试能够继续工作。这些测试针对自己的测试数据库运行,因此我需要能够在运行集成测试时注入测试配置(在POJO /非容器环境中)。
问题是:
一旦我设置了EJB,如果不在容器内运行,我是否无法覆盖注入的bean?
换句话说,在运行原始POJO集成测试时,是否没有直接的方法来注入新的JNDI配置?
示例服务类似于以下内容:
@Stateless(mappedName="MyInterface")
public class MyClassImpl implements MyInterface {
...
@Resource(name="jdbc/MyAppServerDataSourceJNDIName")
DataSource ds;
Connection conn;
...
}
N.B。我不打算将DataSource和Connection留在服务中,我只想在有机重构之前得到一些合理的工作。
我正在考虑的解决方案:
有很多信息,但没有具体的信息(主要是JPA)。虽然在SO的其他地方有一些很好的指示。
提前致谢。
答案 0 :(得分:0)
我的建议:
conn
字段,并始终使用ds.getConnection()
(和conn.close()
)。在单元测试环境中,您可以模拟DataSource / Connection(或以其他方式提供获取并提供连接到测试数据库的“真实”对象)。#2的例子:
@Resource(name="jdbc/MyAppServerDataSourceJNDIName")
public void setDataSource(DataSource ds) {
this.ds = ds;
}
答案 1 :(得分:0)
这是附加样板的框架,用于为您的服务提供可注入的连接(仅限package),以便EJB可用作app-container中的EJB,也可用作本地可配置的junit测试的POJO连接。请注意,还有额外的样板,我们依靠调用#closeConnection来正确管理它。
这个解决方案可以回到最初的问题和bkail的回应:
@Stateless(mappedName = "MyClass")
...
public class MyClass {
// DataSource as configured for app-server environment
@Resource(name="app-dataSource")
private DataSource appDataSource;
private Connection conn;
/**
* Injectable {@code Connection} for injection by unit tests.
*/
/*package-private*/ void setConnection(Connection conn) {
this.conn = conn;
}
/**
* Get {@code Connection}. Use injected Connection if supplied, otherwise
* obtain one from the datasource. Client is responsible for closing this
* through call to #closeConnection (only!).
*/
final Connection getConnection() {
if (this.conn != null) {
return this.conn;
} else {
//Needs exception handling
//
return getDataSource().getConnection)
}
}
/*package-private*/ final void closeConnection(Connection conn) {
if (conn != null && conn != this.conn) {
try{
conn.close();
} catch ... {}
}
}
/*
* Accessor for the {@code DataSource}.
* @return the DataSource
*/
private DataSource getDataSource() {
if (ds == null) {
...
ds = (DataSource) ctx.lookup(jndiName);
...
}
return ds;
}
...
}
public class TestMyClass {
private Connection conn = null;
@BeforeClass
public void setUpBeforeClass() throws Exception {
...
conn = DriverManager.getConnection(...);
}
@Test
public void testMyMethod {
MyClass mc = new MyClass();
mc.setConnection(conn); // Set our own connection
// do test stuff
...
}
...
}