如何在Java Web应用程序中使用DataSource测试DAO?

时间:2015-02-07 11:08:45

标签: java unit-testing datasource jndi dao

我正在使用Tomcat 7JSPServletsLog4jMySQL开展我的项目。

我已经用Google搜索了几个小时没有正确答案的问题。

如何使用DataSourceJUnit测试我的DAO?

我最近发现了这个article,但是不知道如何为我的目的配置它,并且不确定它是否是一种很好的方法。

我有以下DAO层次结构: dao hierarchy

我正在通过以下方式获取DataSource中的AbstractRepository

...
protected final DataSource ds;
...
    public AbstractRepository() {
        DataSource dataSource = null;
        try {
            Context initContext = new InitialContext();
            dataSource = (DataSource) initContext
                    .lookup("java:/comp/env/jdbc/mydb");
        } catch (NamingException ex) {
            LOG.error("Cannot obtain a connection from the pool", ex);
        }
        ds = dataSource;
    }
...

您是否会为解决此问题的方法生成一些代码示例,例如Entrant Repository Test

3 个答案:

答案 0 :(得分:1)

AbstractRepository中的代码很难测试。原因是"智能构造函数",它知道从何处获取数据源。但是你仍然有很多选择。您可以更改代码(我的选择),以便构造函数接收DataSource作为参数,例如

public AbstractRepository(DataSource dataSource){
  this.ds = dataSource;
}

这样您就可以使用一些测试数据源(模拟?)在Test环境中初始化您的存储库。

或者您可以使用一些模拟框架,例如EasyMock,用于创建要测试的存储库的部分模拟。 EasyMock默认情况下不会调用任何构造函数来创建类的部分模拟。那么你可以模拟getDataSource()方法(我希望你有一个方法,用于访问数据源需要的任何地方吗?)来返回测试数据源,或者你可以使用ds字段来设置反思(我想是更糟糕的选择)。

答案 1 :(得分:1)

问题是您的代码直接从源获取其依赖关系。我之前提供的question建议与Alexey Gromov的建议类似,但如果由于某种原因您无法更改代码,则需要在单元测试中执行以下操作:

1)创建通常使用Java容器(例如Tomcat,Jetty)为您创建的子上下文。可以使用我从链接获得的以下命令(我验证它们有效)来完成:

    System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
            "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(Context.URL_PKG_PREFIXES, 
            "org.apache.naming");  

    Context ic = new InitialContext();
    ic.createSubcontext("java:");
    ic.createSubcontext("java:/comp");
    ic.createSubcontext("java:/comp/env");
    ic.createSubcontext("java:/comp/env/jdbc");

2)您需要将模拟对象绑定到您的代码所期望的名称。这可以使用InitialContext#bind。

完成
ic.bind("java:/comp/env/jdbc/DSTest", mock(DataSource.class)); 

请注意,模拟功能由Mockito提供......你可以传递你想要的任何模拟对象。

在我的实际代码中,我有这个:

        mysqlDs = (DataSource) initCtx.lookup("java:/comp/env/jdbc/DSTest");
        System.out.println("----mysqlDs = " + mysqlDs + "\n");

打印出来:

----mysqlDs = Mock for DataSource, hashCode: 1926808117

答案 2 :(得分:0)

使用TomcatJNDI,您可以从类中轻松访问Tomcat JNDI环境,就像您的应用程序在Tomcat中运行一样。 TomcatJNDI利用Tomcat的JNDI系统并通过处理原始Tomcat配置文件来配置它。它的用法很简单,例如。克。

TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.processWebXml(webXmlFile);
tomcatJNDI.start();

此后,您可以像以前一样查找DataSource。 More information can be found here.