我有一个带有JSF页面的maven WAR包。通常我用
@Resource(name = "jdbc/Oracle")
private DataSource ds;
在Glassfish服务器上部署WAR包时调用数据库。但是在JUnit测试的情况下,当我使用netbeans在笔记本电脑上构建软件包时,我无法使用此数据源。 我怎么能解决这个问题?我想在构建软件包后立即使用数据库表运行JUnit测试,但我没有数据源。 有哪些可能的解决方案?
答案 0 :(得分:3)
您真的想对数据库运行单元测试吗?我个人会尽量避免这种情况,因为它通常会将测试与数据库的状态过于紧密联系,并且常常会阻止您实际测试“单位”以及您可能想要处理的所有可能状态。它也可能使你的单元测试需要一些时间来运行,这是不理想的。
另一种方法是使用例如EasyMock或Mockito创建模拟DataSource
。或者您可以创建自己的DataSource
接口的模拟实现,如果您知道要在许多测试中为DataSources
定义一些常见行为。
如果您真的想使用数据库,则必须手动实例化您正在使用的DataSource
的任何实现(例如OracleDataSource
),然后在您的类中使用它。
在任何一种情况下,您可能都必须切换到使用constructor or method injection,以便在您正在测试的实例上设置DataSource
更容易一些。 (否则你将不得不使用反射来设置私有变量。)
例如,您的课程可能如下所示:
public class DatabaseOperations {
private DataSource dataSource;
@Resource(name = "jdbc/Oracle")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
然后您的测试可能如下所示:
public class DatabaseOperationsTest {
public void testSomeOperation() {
DatabaseOperations databaseOperations = new DatabaseOperations();
databaseOperations.setDataSource(new MockDataSource());
}
}
答案 1 :(得分:1)
如果你真的需要使用注入的DataSource运行测试,你可以考虑使用Arquillian,它将为你创建一个部署单元,将它部署到一个embedeed或远程Glassfish容器,以及一个专门用于测试的配置DataSource你希望。对于这种特定情况,他们有guide。
优点是你将拥有一个带有CDI的成熟容器。您可以控制获取包的内容,以便为CDI类提供测试存根。您还可以控制部署配置(测试与生产配置)。它是非侵入性的。