简体   繁体   English

如何在Junit中调用数据源

[英]How to call datasource in Junit

I have a maven WAR package with JSF pages. 我有一个带有JSF页面的Maven WAR软件包。 Usually I use 通常我用

@Resource(name = "jdbc/Oracle")
    private DataSource ds;

to call database when I deploy the WAR package on Glassfish server. 在Glassfish服务器上部署WAR软件包时调用数据库。 But in case of JUnit tests when I build the package on my laptop with netbeans I cannot use this datasource. 但是在使用Netbeans在笔记本电脑上构建软件包时,如果进行JUnit测试,则无法使用此数据源。 How I can solve this problem? 我该如何解决这个问题? I want to run the JUnit tests with database tables right after I build the package but I don't have a datasource. 构建软件包后,我想立即用数据库表运行JUnit测试,但没有数据源。 What are the possible solutions? 有什么可能的解决方案?

Do you actually want to run your unit tests against the database? 您是否真的要针对数据库运行单元测试? Personally I would try to avoid this, since it usually ties the test too closely to the state of the database and often prevents you from actually testing the "unit" and all the possible states you might like to handle. 我个人会尽量避免这种情况,因为它通常将测试与数据库状态联系得太紧,并且经常阻止您实际测试“单元”以及您可能要处理的所有可能状态。 It will also probably make your unit tests take some time to run, which is not ideal. 这也可能会使您的单元测试花费一些时间,这并不理想。

An alternative would be to create a mock DataSource , using for example EasyMock or Mockito . 一种替代方法是使用例如EasyMockMockito创建模拟DataSource Or you could create your own mock implementation of the DataSource interface, if you know you would like to define some common behaviour for DataSources across many tests. 或者,如果您知道要在许多测试中为DataSources定义一些常见行为,则可以创建自己的DataSource接口的模拟实现。

If you really want to use the database, you would have to look at manually instantiating whatever implementation of DataSource you are using (eg OracleDataSource ) and then using this in your class. 如果您确实想使用数据库,则必须查看手动实例化您正在使用的DataSource任何实现(例如OracleDataSource ),然后在您的类中使用它。

In either case, you will probably have to switch to using constructor or method injection to make it a bit easier to set the DataSource on the instance you are testing. 无论哪种情况,您都可能不得不切换到使用构造函数或方法注入,以使其在测试实例上设置DataSource更加容易。 (Otherwise you will have to use reflection to set the private variable.) (否则,您将必须使用反射来设置私有变量。)

For example, your class might look like this: 例如,您的班级可能看起来像这样:

public class DatabaseOperations {
    private DataSource dataSource;

    @Resource(name = "jdbc/Oracle")
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

And then your test might look like this: 然后您的测试可能如下所示:

public class DatabaseOperationsTest {
    public void testSomeOperation() {
        DatabaseOperations databaseOperations = new DatabaseOperations();
        databaseOperations.setDataSource(new MockDataSource());
    }
}

If you really do need to run tests using an injected DataSource, you could consider using Arquillian which will create a deployment unit for you, deploy it to either an embedeed or remote Glassfish container, together with a configured DataSource specifically for testing if you wish. 如果确实需要使用注入的数据源运行测试,则可以考虑使用Arquillian,它将为您创建一个部署单元,将其与配置好的数据源一起部署到嵌入式或远程Glassfish容器中(如果需要)。 They have a guide for this specific scenario. 他们有针对此特定方案的指南

The advantage is that you will have a full-blown container with CDI. 好处是您将拥有一个带有CDI的功能齐全的容器。 You control what gets package so you can provide test stubs for CDI classes. 您可以控制获取软件包的内容,以便为CDI类提供测试存根。 You can also control the deployment configuration (test vs. production configuration). 您还可以控制部署配置(测试与生产配置)。 It is non-invasive. 它是非侵入性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM