2013-02-19 85 views
0

我有这个简单的CDI Bean上显示的内容为JSF页面:JUnit中无法找到数据源测试

@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数据源吗?

回答

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); 

    } 

}

+0

我不使用Spring到我的代码。我可以用别的东西来替换'SpringJUnit4ClassRunner'吗? – 2013-02-19 19:53:17

+0

对不起,我以为你在使用Spring MVC,你可以使用我提到的第一个解决方案。我编辑了我的答案来澄清。 – mtrovo 2013-02-19 20:17:08

+0

是的,它工作得很好。谢谢! – 2013-02-19 20:32:54