我有一个带有 JSF 页面的 Maven WAR 包。通常我使用
@Resource(name = "jdbc/Oracle")
private DataSource ds;
在 Glassfish 服务器上部署 WAR 包时调用数据库。但是,当我在笔记本电脑上使用 netbeans 构建包时,如果进行 JUnit 测试,我将无法使用此数据源。我该如何解决这个问题?我想在构建包后立即使用数据库表运行 JUnit 测试,但我没有数据源。有哪些可能的解决方案?
你真的想对数据库运行单元测试吗?我个人会尽量避免这种情况,因为它通常将测试与数据库状态联系得太紧密,并且经常阻止您实际测试“单元”以及您可能想要处理的所有可能状态。它还可能使您的单元测试需要一些时间才能运行,这并不理想。
另一种方法是创建一个模拟DataSource
,例如使用EasyMock或Mockito。DataSource
或者,如果您知道要为DataSources
许多测试定义一些通用行为,您可以创建自己的接口模拟实现。
如果您真的想使用数据库,您将不得不查看手动实例化DataSource
您正在使用的任何实现(例如OracleDataSource
),然后在您的类中使用它。
在任何一种情况下,您可能都必须切换到使用构造函数或方法注入,以便更容易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());
}
}
如果您确实需要使用注入的 DataSource 运行测试,您可以考虑使用 Arquillian,它将为您创建一个部署单元,将其部署到嵌入式或远程 Glassfish 容器,如果您愿意,还可以配置一个专门用于测试的 DataSource。他们有针对这种特定情况的指南。
优点是您将拥有一个带有 CDI 的成熟容器。您可以控制获取包的内容,以便为 CDI 类提供测试存根。您还可以控制部署配置(测试与生产配置)。它是非侵入性的。