I wrote a mock framework last weekend, to address in internal unit testing problems
in my current job. The module i worked on is a small piece of a complicated system in world's biggest online retail company, and it depends heavily on downstream services. basically no unit test code at all in the original system.
Mock object helps but it is not easy to use. Finally i decided to create a new one, which
1. define testing data in the separate xml file [ promote reuse]
2. define mock contracts in the separate xml file [ promote reuse and easy understanding]
SecondMock 1.0 Readme
The SecondMock allows to generate Mock Objects for classes and interfaces, with mocked behavior defined in the contracts.
Requirements
The SecondMock requires
Java 5 or above,
cglib 2.1
asm
objenesis
beanutils
Usage
To generate Mock Objects for classes and interfaces, use
SecondMock mock = new SecondMock(); mock.registerDataFile("testdata-1.xml");
To register test data which can be reused in different test plans.
You will then create a mock
ToMock service = mock.createSecondMock("name", ToMock .class, MockPolicy.NORM, "testplan-1.xml");
or
ToMock service = mock.createSecondMock(ToMock .class, "testplan-1.xml");
with given test plan which defines the test contracts.
Here ToMock can be interface or class.
How to plugin different test plan implementation?
Different test plan implementation strategies can be plugin.
in the test plan xml file
<TestPlan name="test" impClass="org.second.life.mock.BaseTestPlan">
impClass must implement TestPlan interface. Default implementation, if not specified, will be BaseTestPlan.
How to define the test data?
Test data is defined in the seperate xml file to promote data reuse.
<dataset namespace="test">
<objects class="org.second.life.mock.Employee">
<object id="foo" singleton="true">
<property name="name"><objectref refid="1"/></property>
<property name="alias" type="List">I, am , Fine</property>
<property name="personalities" type="Map">fishing,good,boxing,hate,travel,ok</property>
</object>
</objects>
<objects class="org.second.life.mock.Name">
<object id="1" singleton="true">
<constructor>
<property name="firstName" type="string">Brian</property>
<property name="lastName" type="string">King</property>
</constructor>
</object>
<object id="2" singleton="true">
<constructor>
<property name="firstName" type="string">Brian</property>
<property name="lastName" type="string">King</property>
</constructor>
</object>
</objects>
</dataset>
The object can be referenced accross namespace
How to define the contracts
<TestPlan name="test" impClass="org.second.life.mock.BaseTestPlan">
<!-- it should be implementation dependent? -->
<contract-list>
<contract>
<!-- not used yet -->
<precondition>
</precondition>
<method name="reverse"/>
<input>
<parameter name="input" type="string" value="123"/>
</input>
<return>
<!-- refid can be from input parameter or data section -->
<!-- <objct refid=/> -->
<!-- or return as name value pair -->
<result name="input" type="string" value="321"/>
</return>
</contract>
<contract>
<!-- not used yet -->
<precondition>
</precondition>
<method name="reverse"/>
<input>
<parameter name="input" type="string" value="111"/>
</input>
<return>
<!-- refid can be from input parameter or data section -->
<!-- <objct refid=/> -->
<!-- or return as name value pair -->
<exception class="org.second.life.mock.DummyException" message="i am foo" errorcode=""/>
</return>
</contract>
<contract>
<!-- not used yet -->
<method name="getEmployee"/>
<input>
<parameter name="name"><objectref refid="test.1"/></parameter>
</input>
<return>
<result>
<objectref refid="test.foo"/>
</result>
</return>
</contract>
</contract-list>
</TestPlan>
Limitations
Final methods cannot be mocked. If called, their normal code will be executed.
Class instantiation is performed using
Objenesis.
Supported JVMs are listed
here.
Authors
SecondMock is written by Hanning Ni [watchsound@gmail.com]
Mock idea and some implementation initially from Easy Mock [Henri Tremblay]
The Project Hompage
code is available at
http://jtestframework.sourceforge.net/
Release Notes
Initial Release 1.0
Seperate test data and test behavior