我的Java EE 7应用程序使用Spring,在Tomcat 7上运行.它使用JNDI数据源访问数据库,该数据源由context.xml中的此行定义:
<Resource auth="Container" driverClassName="org.postgresql.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/leadmanager" password="xxxxxxxx" type="javax.sql.DataSource" url="jdbc:postgresql://localhost:5432/leadmanager" username="postgres"/>
Run Code Online (Sandbox Code Playgroud)
我创建了一些JUnit测试.当我尝试运行它们时(在Eclipse中,通过右键单击测试类并选择Run As | JUnit Test),发生了异常:
javax.persistence.PersistenceException: [PersistenceUnit: leadmanager] Unable to build EntityManagerFactory
...
Caused by: org.hibernate.service.jndi.JndiException: Error parsing JNDI name [java:/comp/env/jdbc/leadmanager]
...
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
...
Run Code Online (Sandbox Code Playgroud)
感谢这篇有用的帖子 - https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit - 我找到了一个解决方案.我把它添加到我的测试类中:
@BeforeClass
public static void setUpClass() throws Exception {
// create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
PGPoolingDataSource ds = new PGPoolingDataSource();
ds.setServerName("localhost:5432/leadmanager");
ds.setUser("postgres");
ds.setPassword("xxxxxxxx");
ic.bind("java:/comp/env/jdbc/leadmanager", ds);
}
Run Code Online (Sandbox Code Playgroud)
但那太可怕了!我被迫两次定义我的数据源,一次在context.xml中,另一次在我的测试类中.而且我被迫将我的数据库密码存储在Java代码中,该代码将被检入源代码控制.
我已经查阅了这篇文章:在jUnit中设置JNDI数据源
有没有更好的办法?
原因是你的测试不是在tomcat内部运行,而是在单独的JVM实例中运行。
尝试使用Arquillian构建您的单元测试- 该工具会将您的测试打包为一个简单的 Web 应用程序,并在您的 tomcat 中执行。结果是,在 tomcat 中可访问的所有内容都可以在您的测试中访问,包括资源。
| 归档时间: |
|
| 查看次数: |
1816 次 |
| 最近记录: |