我有一个带有JSF页面的maven WAR包。通常我使用如何在Junit中调用数据源
@Resource(name = "jdbc/Oracle")
private DataSource ds;
当我在Glassfish服务器上部署WAR包时调用数据库。但在JUnit测试中,当我使用netbeans在我的笔记本电脑上构建包时,我无法使用此数据源。 我该如何解决这个问题?我想在构建包后立即运行带有数据库表的JUnit测试,但没有数据源。 什么是可能的解决方案?
我有一个带有JSF页面的maven WAR包。通常我使用如何在Junit中调用数据源
@Resource(name = "jdbc/Oracle")
private DataSource ds;
当我在Glassfish服务器上部署WAR包时调用数据库。但在JUnit测试中,当我使用netbeans在我的笔记本电脑上构建包时,我无法使用此数据源。 我该如何解决这个问题?我想在构建包后立即运行带有数据库表的JUnit测试,但没有数据源。 什么是可能的解决方案?
你真的想对数据库运行你的单元测试吗?就我个人而言,我会尽量避免这种情况,因为它通常将测试与数据库状态紧密联系在一起,并且经常会阻止您实际测试“单元”以及您可能想要处理的所有可能状态。它也可能会让你的单元测试花费一些时间来运行,这并不理想。
另一种方法是创建一个模拟DataSource
,例如使用EasyMock或Mockito。或者你可以创建自己的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());
}
}
如果确实需要使用注入的数据源来运行测试,那么可以考虑使用Arquillian,它将为您创建一个部署单元,将其部署到嵌入式或远程Glassfish容器,以及配置的专用于测试的DataSource无线SH。对于这种特定场景,他们有一个guide。
优势是你将拥有一个拥有CDI的成熟容器。您可以控制获取软件包的内容,以便为CDI类提供测试存根。您还可以控制部署配置(测试与生产配置)。它是非侵入性的。