java中数据库连接测试的问题

问题描述

我尝试测试我的 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);
    }

}

解决方法

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 服务器为您执行此操作.