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

How to test DAO with DataSource in Java Web Application?

我正在使用 Tomcat 7JSPServletsLog4jMySQL.

来做我的项目

我在谷歌上搜索了这个问题好几个小时都没有正确答案。

如何使用 DataSourceJUnit 测试我的 DAO?

我最近发现了这个 article,但不知道如何根据我的目的配置它,也不确定这是否是一个好方法。

我有以下 DAO 层次结构:

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

...
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 生成一些代码示例来解决这个问题吗?

您在 AbstractRepository 中的代码很难测试。原因是"smart constructor",知道他从哪里得到数据源。但是您仍然有很多选择。您可以更改代码(我的选择),以便构造函数接收 DataSource 作为参数,例如

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

因此您将能够使用一些测试数据源(模拟?)在测试环境中初始化您的存储库。

或者您可以使用一些模拟框架,例如EasyMock,创建要测试的存储库的部分模拟。 EasyMock 创建 类 的部分模拟,默认情况下不调用任何构造函数。然后你可以模拟 getDataSource() 方法(我希望你有一个,在你需要访问数据源的任何地方都使用它?)到 return 测试数据源,或者你可以设置最终的 ds 字段使用反射(我想是更糟糕的选择)。

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

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

    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)); 

请注意 mock 函数由 Mockito 提供...您可以传递任何您想要的模拟对象。

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

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

打印出:

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

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

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

此后您可以像往常一样查找数据源。 More information can be found here.