Reputation: 1588
I have this simple CDI bean which displays content into JSF page:
@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;
}
.............
}
I created this JUnit test case which calls the Java method:
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);
}
}
I get error at these lines:
if (ds == null)
{
throw new SQLException();
}
How I can solve this problem? I want to use the datasource from the JUnit test during the testing. Can I somehow use the JUnit datasource?
Upvotes: 0
Views: 3591
Reputation: 879
You can make DataSource ds
a JavaBean property and set its value on your JUnit test. This way you hide the complexity of the JNDI binding and focus your tests only on the business logic.
Your controller:
@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;}
...
}
And you test class:
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);
}
}
As a side note, following the MVC design pattern I would even decouple the controller business logic from the database connection, so no valid connection is needed to execute the unit tests and your focus is entirely on the behavior of your controller.
If you are using Spring and want to use all Spring beans within your JUnit class you can always use the @RunWith
JUnit annotation.
@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);
}
}
Upvotes: 1