【问题标题】:Problem with Db connection testing in javajava中的Db连接测试问题
【发布时间】:2021-05-05 15:02:18
【问题描述】:

我尝试测试我的 Dao 类,但它为 DbConnection 类返回此错误:

javax.naming.NoInitialContextException:需要在环境或系统属性中,或在应用程序资源文件中指定类名:java.naming.factory.initial 在 java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:691) 在 java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305) 在 java.naming/javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:342) 在 java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409) 在 model.DbConnection.(DbConnection.java:16) 在 model.DbConnection.getInstance(DbConnection.java:30) 在 model.ProfileManager.ReturnPatientByKey(ProfileManager.java:27) 在 model.ProfileManagerTest.testReturnPatientByKey(ProfileManagerTest.java:32) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.base/java.lang.reflect.Method.invoke(Method.java:564) ……

我的 DbConnection 类:

package model;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DbConnection {

    private DbConnection() {

        Context ctx;
        try {
            ctx = new InitialContext();
            ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    public Connection getConnection() throws SQLException {
        return ds.getConnection();

    }

    public static DbConnection getInstance () {
        if(db==null) {
            return new DbConnection();
        }
        else {
            return db;
        }
    } 

    private static DataSource ds;
    private static DbConnection db;
}

数据库连接在 Web 应用程序中有效,只有测试返回此错误。 我认为问题不在于我的 ProfileManager 类,因为它只是一个测试示例:


import static org.junit.Assert.assertTrue;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import model.Bean.PatientBean;

class ProfileManagerTest{

    private ProfileManager pm;
    String fiscal_code;
    String user_password;
    PatientBean patient;
    
    @BeforeEach
    void setUp() throws Exception {
        this.pm = new ProfileManager();
        fiscal_code = "aaa";
        user_password = "bbb";
        patient = mock(PatientBean.class);
    }

    @AfterEach
    void tearDown() throws Exception {
    }

    @Test
    void testReturnPatientByKey() {
        patient = (PatientBean) pm.ReturnPatientByKey(fiscal_code, user_password);
        assertTrue(true);
    }

}

【问题讨论】:

    标签: java jdbc junit dbconnection


    【解决方案1】:

    数据库连接在Web应用程序中有效,只有测试返回此错误。

    这很可能是因为您在服务器配置中声明了数据源,并且服务器正在为您的 Web 应用程序提供一个数据源,但您在测试中没有这样做。

    在您的服务器文件中进行搜索,您可能会发现类似或类似的内容,具体取决于您使用的服务器:

    <Resource name="jdbc/CheckUpDb" 
      driverClassName="..." 
      type="..." 
      url="..." 
      username="..." 
      password="..." 
    />
    

    这是configure a datasource using JNDI 的一种方式。当您的 Web 应用程序运行时,服务器将按名称为您提供此资源。这就是ctx.lookup("java:comp/env/jdbc/CheckUpDb"); 所做的。它要求服务器提供该资源。

    但是当您运行单元测试时,您是在服务器环境之外运行的。这意味着您在服务器中定义的任何资源(例如使用context.xml)在您运行测试时都不存在。在您的测试中,您必须提供一个数据源并使其可用于您的 JNDI 上下文,这样这行代码才能工作:

    ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
    

    以下帖子应为您提供必要的详细信息,以便为您的测试设置 JNDI 数据源:Setting up JNDI Datasource in jUnit

    您将看到那里的示例使用了一个名为 Simple-Jndi 的库,他们使用该库来提供 JNDI 上下文并将其配置为包含测试然后尝试按名称检索的数据源。您可以使用任何 JNDI 提供程序,但您必须自己设置测试的数据源(在 @BeforeEach@BeforeAll 内),因为在运行单元测试时,您没有 tomcat 服务器为您执行此操作。

    【讨论】:

    • 在一个 Maven 项目中使用 Tomcat 和 Eclipse。我应该在哪里输入您写的内容?我试图将此代码插入到 Tomcat 的 context.xml 文件中,但它给了我同样的错误:&lt;Resource url="jdbc:mysql://127.0.0.1:3306/CheckUpDb?useUnicode=true&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=CET" password="martina" username="root" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" maxWait="10000" maxIdle="10" maxActive="20" auth="Container" name="jdbc/CheckUpDb"/&gt;
    • 你说数据库连接在web应用程序中有效,只有测试返回这个错误。您是否从tomcat运行单元测试?这似乎不对。如果 Web 应用程序正常工作,那么您必须在某处已经声明了 CheckUpDb。你搜索过吗?在单元测试中,您将在 @BeforeEach@BeforeAll 中设置上下文,具体取决于您希望如何运行测试。
    • stackoverflow.com/questions/66036577/… @Bogdan 这是我所有的代码。测试和被测类在同一个项目中。是的,数据库连接工作正常,但单元测试是问题所在。我正在使用 junit-jupiter 5.6.0 版。您如何在链接中看到, CheckUpDb 已在 context.xml 中声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2015-11-03
    相关资源
    最近更新 更多