我有这个简单的CDI bean,它将内容显示在JSF页面中:
@Named("ZonesController")
@ViewScoped
public class Zones implements Serializable
{
@Resource(name = "jdbc/Oracle")
private DataSource ds;
...........
public int countDBRowNum() throws Exception
{
String SqlStatement = null;
if (ds == null)
{
throw new SQLException();
}
Connection conn = ds.getConnection();
if (conn == null)
{
throw new SQLException();
}
PreparedStatement ps = null;
ResultSet resultSet = null;
int count = 0;
try
{
conn.setAutoCommit(false);
boolean committed = false;
try
{
SqlStatement = "SELECT COUNT(1) FROM component x, componentstats y WHERE x.componentstatsid = y.componentstatsid AND y.componenttypeid = 1100";
ps = conn.prepareStatement(SqlStatement);
resultSet = ps.executeQuery();
if (resultSet.next())
{
count = resultSet.getInt(1);
}
conn.commit();
committed = true;
}
finally
{
if (!committed)
{
conn.rollback();
}
}
}
finally
{
ps.close();
conn.close();
}
// Returns total rows in table.
return count;
}
.............
}
我创建了这个调用Java方法的JUnit测试用例:
public class ZonesTest
{
@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");
// Construct DataSource
OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@192.168.1.104:1521:oracle");
ds.setUser("admin");
ds.setPassword("qwerty");
ic.bind("java:/comp/env/jdbc/oracle", ds);
}
catch (NamingException ex)
{
//Logger.getLogger(MyDAOTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Test
public void testCountDBRowNum() throws Exception
{
Zones instance = new Zones();
int rows = instance.countDBRowNum();
System.out.println(rows);
}
}
我在这些方面遇到错误:
if (ds == null)
{
throw new SQLException();
}
我如何解决这个问题?我想在测试期间使用JUnit测试中的数据源。我可以以某种方式使用JUnit数据源吗?
答案 0 :(得分:1)
您可以使DataSource ds
成为JavaBean属性,并在JUnit测试中设置其值。这样,您可以隐藏JNDI绑定的复杂性,并将测试仅集中在业务逻辑上。
你的控制器:
@Named("ZonesController")
@ViewScoped
public class Zones implements Serializable
{
@Resource(name = "jdbc/Oracle")
private DataSource ds;
public void setDs(DataSource ds){this.ds=ds;}
public DataSource getDs(){return ds;}
...
}
你测试课程:
public class ZonesTest
{
private static OracleConnectionPoolDataSource ds;
@BeforeClass
public static void setUpClass() throws Exception
{
try
{
// Construct DataSource
ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@192.168.1.104:1521:oracle");
ds.setUser("admin");
ds.setPassword("qwerty");
}
catch (NamingException ex)
{
//Logger.getLogger(MyDAOTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Test
public void testCountDBRowNum() throws Exception
{
Zones instance = new Zones();
instance.setDs(ds);
int rows = instance.countDBRowNum();
System.out.println(rows);
}
}
作为旁注,在MVC design pattern之后我甚至会将控制器业务逻辑与数据库连接分离,因此执行单元测试不需要有效连接,而您的重点完全在于控制器的行为
如果您正在使用Spring并希望在JUnit类中使用所有Spring bean,则可以始终使用@RunWith
JUnit注释。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ZonesTest
{
@Autowire
Zones zones;
// your BeforeClass method here
@Test
public void testCountDBRowNum() throws Exception
{
int rows = zones.countDBRowNum();
System.out.println(rows);
}
}