0

コンテンツを JSF ページに表示するこの単純な CDI Bean があります。

@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 データソースを使用できますか?

4

1 に答える 1

1

JavaBean プロパティを作成DataSource dsし、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 設計パターンに従って、コントローラーのビジネス ロジックをデータベース接続から切り離すこともできるため、単体テストを実行するために有効な接続は必要なく、コントローラーの動作に完全に集中できます。

Spring を使用していて、JUnit クラス内ですべての Spring Bean を使用したい場合は、いつでも@RunWithJUnit アノテーションを使用できます。

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

    }

}

于 2013-02-19T19:23:15.483 に答える