如何在 Java Web 应用程序中使用 DataSource 测试 DAO?
How to test DAO with DataSource in Java Web Application?
我正在使用 Tomcat 7
、JSP
、Servlets
、Log4j
和 MySQL
.
来做我的项目
我在谷歌上搜索了这个问题好几个小时都没有正确答案。
如何使用 DataSource
和 JUnit
测试我的 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.
我正在使用 Tomcat 7
、JSP
、Servlets
、Log4j
和 MySQL
.
我在谷歌上搜索了这个问题好几个小时都没有正确答案。
如何使用 DataSource
和 JUnit
测试我的 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
字段使用反射(我想是更糟糕的选择)。
问题是您的代码直接从源代码获取依赖项。我为您提供的先前
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.