Mock Junit Test Framework

advertisement

Mock junit framework uses prepopulated mock java objects instead
of live database connection for
executing the unit test cases.
Service Layer
DAO Layer
DataBas
e

The service Layer invokes the DAO layer for getting
data from the Database.

The DAO pulls data from Database and constructs
objects and returns it to Service Objects.

public interface StockItemCountService {
public int getStockItemCount(String warehouseCode);
……………………
Service
Interface
}
public class StockItemCountServiceImpl implements StockItemCountService {
private StockItemCountDao stockItemCountDao;
}
public void setStockItemCountDao(StockItemCountDao stockItemCountDao) {
this.stockItemCountDao = stockItemCountDao;
public StockCount getStockItemCountData(StockCount data){
return stockItemCountDao.getStockItemCountData(data);
Service
Implementati
on
This dao is a
dependency of the
service Object. At
runtime spring
injects a DAO
implementation
depending upon the
spring XML files.
The following is an excerpt from spring-beans.xml injecting a DAO
implementation.
<bean id="StockItemCountService"
class="org.kuali.ext.mm.service.impl.StockItemCountServiceImpl">
<property name="stockItemCountDao">
<ref bean="stockItemCountDao" />
DAO
</property>
dependency
</bean>
injection
<bean id="stockItemCountDao"
class="org.kuali.ext.mm.dataaccess.impl.StockItemCountDaoOjb"
/>
</beans>
Service Layer
DAO Layer
Object
Fixtures

The service Layer invokes the DAO layer for getting
data from the Database.

The DAO instead of pulling data from Database it
pulls data from property files using Fixture objects.
The service layer remains the same in both the cases.
only the








All the testcases should be a subclass of
org.kuali.ext.mm.sys.context.KualiMockTestBase.
public class StockItemCountServiceImplTest extends
KualiMockTestBase {
private org.kuali.ext.mm.service.StockItemCountService
serviceObject;
In the setup()
method get the
service object to be
unit tested from the
spring context.
@Before
public void setUp() throws Exception {
serviceObject =
(org.kuali.ext.mm.service.StockItemCountService)
SpringContext.getBean(StockItemCountServiceImpl.class);
}


Create a DAO object in test folder using the
same package structure of its corresponding
DAO in src folder(both the DAOs should
implement the same DAO interface).
In your testcase prepare the input data object
(data object to be passed to the service layer)
and output data object (data object that would
be returned from the DAO layer if it connects
to the database)








If a new DAO or service is to be tested then corresponding entries
should be made in mm-dev\src\conf\project\spring-mmService entry
test.xml.
should be
same for test
and src
<bean id="StockItemCountService"
class="org.kuali.ext.mm.service.impl.StockItemCountServiceImpl">
<property name="stockItemCountDao">
TestDAOs are
<ref bean="stockItemCountDao" />
injected
</property>
instead of
</bean>
Real DAOs
<bean id="stockItemCountDao"
class="org.kuali.ext.mm.dataaccess.impl.TestStockItemCountDaoOjb"
/>



Populate the test DAO cache with the prepared
output Data Object.
If the service layer invokes multiple DAOs then
caches of all the corresponding test DAOs need
to be populated with the output data object.
Invoke the testcase.
Cache contains
data object
keyed by Id of
the object.

public class xxxDAO implements IxxxDAO{Common
interface for
both mock
and database
DAOs.
protected cache Map<key, Object>
public void addData(Object data){
cache.add(data.getId(), data);
}
Method for
public void clear(){
adding data to
cache.clear()
cache.
}
……… DAO interface methods implementation

}
DAO interface
implementations
using cache for
data instead of
database
Input and output
data objects are
prepared.
public class xxxTestCase extends KualiTestBase{
StockCount inputData = prepareStockCountData();
StockCount outputData = prepareStockCountData();
inputData.setBeforeItemQty(new KualiDecimal("1"));
outputData.setStockCountItemQty(new KualiDecimal("1"));
Populate the
cache of the
DAO with the
prepared
output data.
org.kuali.ext.mm.dataaccess.impl.TestStockItemCountDaoOjb dao = new
org.kuali.ext.mm.dataaccess.impl.TestStockItemCountDaoOjb();
Invoke the
dao.clear();
service layer
dao.addStockData(outputData);
methods
serviceObject.updateStockItemCountStatus(inputData);
with the
StockCount iinputData = serviceObject.getStockItemCountData(inputData);prepared
input data
assertEquals("Correct Code",
iinputData.getStockTransReasonCd(),TestConstants.STOCK_TRANS_REASON_CODE_GOOD);

There two ways of constructing Data Objects
for input and output.

Automatically construct the Object using Fixture
objects which pull data from property files.

Manually creating object and populating it using its
constructor or setter methods.


Provide a private method in your testcase for
creating the test data object and invoke it for
getting the data.
Private StockCount prepareStockCount(){
StockCount aStockCount = new StockCount();
aStockCount.setId(“hfjdf”);
…………………
return aStockCount;
}








public enum StockItemCountFixture {
STOCKITEMCOUNT(1), STOCKITEMCOUNT1(2), STOCKITEMCOUNT2(3),
STOCKITEMCOUNT3(4);
private int testDataPos;
String propertiesFileName =
"org/kuali/ext/mm/service/data/stock_item_count_service.properties";
properties.load(ClassLoader.getSystemResourceAsStream(propertiesFileName));
private StockItemCountFixture(int dataPos) {
this.testDataPos = dataPos;
}


public StockCount newStockCount() {







String propertyKey = "stockCount.testData" + testDataPos;
String deliminator = properties.getProperty("deliminator");
String fieldNames = properties.getProperty("stockCount.fieldNames");
StockCount stockCountData = TestDataPreparator.buildTestDataObject(StockCount.class,
properties, propertyKey, fieldNames, deliminator);
return stockCountData;
}

Advantages of Mock Objects
Doesn’t need expensive database connections for
running the test cases
 Test case execution will be very fast and easy as
there is no database connection.
 Test cases are independent of changes in database
tables.
 Test cases can be executed anywhere at anytime.


Disadvantages of Mock Objects

Since database is not used , we can’t implement test
cases for database (transaction) and OJB (persistence
APIs) layer properties.

Requires coding of DAOs with cache of objects.

Requires a very good understanding of data model
and the service layer.
Download