Wednesday, October 01, 2003

MOCK OBJECTS
1. I always had this desire to be able to run test Application . Standalone. Ie without any external dependency.
By external dependencies I mean
1. DataBase
2. Outside of Application Server (No JNDI dependencies)
3. can test my code outside of browser environment.

My discoveries.
1. Running an Application stand alone with the DB using MOCK objects is a Dream that cannot be fullfilled .

Reasons
a) you will end up spending more time writing the MOCK DATA Objects.
b) most of the test conditions will involve working with the Data. and hence the Mock data object approach fails. So Try to setup the DAtabse ASAP. it is not very expensive. DBs like mysql are very lightweigth More Later.....

Solution
Instead have an approach like this.
1. Write your test Data in Excel
2. Save it to CSV.
3. Write a Junit Test or a Command to load the all the data before running any test.

example :

package test.daos;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

import com.dclab.base.AbstractTestCase;
import com.dclab.base.persist.PersistanceManager;

/**
* Class FirstTest.java Created on Sep 26, 2003

*
*/
public class FirstTest extends AbstractTestCase {

/**
* Constructor for FirstTest.
* @param arg0
*/
public FirstTest(String arg0) {
super(arg0);
}

/**
* @see AbstractTestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
}

/**
* @see AbstractTestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
}


public void testLoadDataForPhotoInfo() throws Exception{
PersistanceManager.Instance().startTransaction();
Connection con = PersistanceManager.Instance().getConnection();
Statement st = con.createStatement();

File f = super.getTestDataFile("testcases/testdata/photoinfo.csv");

super.display("File is " + f.toURL().getFile());

String sql = "LOAD DATA LOCAL INFILE '";
sql += f.toURL().getFile();
sql += "' INTO TABLE photodb.photoinfo " ;
sql += " fields terminated by ',' lines terminated by '\\r\\n' IGNORE 1 LINES;";
super.display("SQL is = " + sql);

st.execute(sql);
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();

}

public void testLoadDataForAlbum() throws Exception{
PersistanceManager.Instance().startTransaction();
Connection con = PersistanceManager.Instance().getConnection();
Statement st = con.createStatement();

File f = super.getTestDataFile("testcases/testdata/album.csv");

super.display("File is " + f.toURL().getFile());

String sql = "LOAD DATA LOCAL INFILE '";
sql += f.toURL().getFile();
sql += "' INTO TABLE photodb.album " ;
sql += " fields terminated by ',' lines terminated by '\\r\\n' IGNORE 1 LINES;";
super.display("SQL is = " + sql);

st.execute(sql);
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();

}

public void testloadDataForUsr() throws Exception {
PersistanceManager.Instance().startTransaction();
Connection con = PersistanceManager.Instance().getConnection();
Statement st = con.createStatement();

File f = super.getTestDataFile("testcases/testdata/User.csv");

super.display("File is " + f.toURL().getFile());

String sql = "LOAD DATA LOCAL INFILE '";
sql += f.toURL().getFile();
sql += "' INTO TABLE photodb.user " ;
sql += " fields terminated by ',' lines terminated by '\\r\\n' IGNORE 1 LINES;";
super.display("SQL is = " + sql);

st.execute(sql);
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();

}


public void testDeleteAllFromUser() throws Exception{
PersistanceManager.Instance().startTransaction();
Connection con = (Connection)PersistanceManager.Instance().getConnection();
PreparedStatement stmt = con.prepareStatement("delete from user");
stmt.executeUpdate();
stmt.close();
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();
}

public void testDeleteAllFromAlbum() throws Exception{
PersistanceManager.Instance().startTransaction();
Connection con = (Connection)PersistanceManager.Instance().getConnection();
PreparedStatement stmt = con.prepareStatement("delete from album");
stmt.executeUpdate();
stmt.close();
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();
}

public void testDeleteAllFromPhotos() throws Exception{
PersistanceManager.Instance().startTransaction();
Connection con = (Connection)PersistanceManager.Instance().getConnection();
PreparedStatement stmt = con.prepareStatement("delete from photoinfo");
stmt.executeUpdate();
stmt.close();
PersistanceManager.Instance().commit();
PersistanceManager.Instance().release();
}



}


As seen above this is the First Test that gets executed..... this test deletes all the Data then loads all the data into DB before running.

Note Please note that I am loading data from CSV's in a machine independent way.


USE of Mock objects
I think mock objects could be very useful when intigrating with other systems where you are really talking to the other system in a service mode
Daily Builds
It is very essential to get to a stage of Daily builds and the Tests incorporated into the build itself.

Best Practice.
Try to do the following
1. Code in SRC
2. Test code in
testhome\test\* Junit Test cases
testhome\testcases\*.xml your test cases
testhome\testcases\*.csv your Test Data (to be loaded into DB)