I'm trying to run this JUnit test but I get NPE:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class KnowledgebaseTest
{
public KnowledgebaseTest()
{
}
@BeforeClass
public static void setUpClass() throws Exception
{
try
{
// 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");
String host = "localhost";
int port = 5432;
String dbName = "crm";
String username = "postgres";
String password = "qwerty";
Class.forName("org.postgresql.Driver");
Connection conn = null;
conn = DriverManager.getConnection("jdbc:postgresql://" + host + ":" + port + "/" + dbName, username, password);
conn.close();
ic.bind("java:/comp/env/jdbc/nameofmyjdbcresource", conn);
}
catch (NamingException ex)
{
Logger.getLogger(KnowledgebaseTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
@AfterClass
public static void tearDownClass()
{
}
@Before
public void setUp()
{
}
@After
public void tearDown()
{
}
@Resource(name = "java:/comp/env/jdbc/nameofmyjdbcresource")
DataSource ds;
@Test
public void testPageFirst() throws SQLException
{
if (ds == null)
{
throw new SQLException("Can't get data source");
}
Connection conn = ds.getConnection();
if (conn == null)
{
throw new SQLException("Can't get database connection");
}
PreparedStatement ps = null;
boolean committed = false;
try
{
conn.setAutoCommit(false);
ps = conn.prepareStatement("UPDATE ACCOUNT SET LAST_LOGIN = CURRENT_DATE WHERE USER_NAME = ?");
ps.setString(1, "TIMESTAMP");
ps.executeUpdate();
ps.close();
conn.commit();
committed = true;
}
finally
{
if (!committed)
{
conn.rollback();
}
if (ps != null)
{
ps.close();
}
conn.close();
}
}
}
For some reason ds is null. What is the proper way to initialize Data source object in JUnit test file?
java.sql.SQLException: Can't get data source
Can you propose some solution to fix this issue or better solution?
答案 0 :(得分:2)
您的代码似乎不正确您应该绑定数据源而不是连接。要修复代码(假设您使用PGSQL),您需要绑定数据源,如下所示:
import org.postgresql.jdbc2.optional.SimpleDataSource;
...
SimpleDataSource dataSource = new SimpleDataSource();
dataSource.setDatabaseName(dbName);
dataSource.setPortNumber(port);
dataSource.setUser(username);
dataSource.setPassword(password);
ic.bind("java:/comp/env/jdbc/nameofmyjdbcresource", dataSource);
然后您可以将setUp方法中的变量设置为下一个:
DataSource ds;
@Before
public void setUp() throws NamingException {
this.ds = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/nameofmyjdbcresource");
}
无论如何,JUnit中没有默认魔法可以允许你注入数据源,因此如果你想与你最喜欢的JEE服务器进行真正的集成测试,那么JUnit默认会忽略@Resource(name = "java:/comp/env/jdbc/nameofmyjdbcresource")
/资源注入,您可以查看arquillian