Tuesday, June 26, 2007
Amock 9.6
1. Features
With Amock, you
Can mock static method and constructor.
- You can unit test with singleton.
Can create mock object of a class which have only private constructor.
Can create mock instance of interface and normal class instance.
Can create mock object without any parameter even if the class does not have default constructor.
- You don’t need to create expensive object just for mock constructor.
Can access private method and attribute easily.
Can mock private and protected method.
Can use argument checker (argument matcher 'eq(). any()...') only where it is needed.
Can change final variable.
Can change String value.
Don’t need extending specific class.
2. Setup environment
2.1. Prerequisite
JDK 1.5 version
http://java.sun.com/javase/downloads/index_jdk5.jsp
Eclipse 3.2
http://www.eclipse.org/downloads/AJDT 1.4.0
http://www.eclipse.org/downloads/AJDT 1.4.0
Download Amock libarary and documentation from
and CGlib no dependency 2.1_3
2.2. Setup eclipse
To use this libraryFirst change project to AspectJ project.
Second, Add 'Amock-bin.jar' in your AspectJ Aspect path.
Third, Add 'Amock-bin.jar' and 'cglib-nodep-2.1_3.jar' in your Class path.
Now you ready to use Amock.
3. Sample Example
package my.amock.example;
import static my.amock.util.Will.*;
import static my.amock.util.A.*;
import static my.amock.check.Check.*;
import my.amock.bracket.Story;
import my.amock.util.A;
import my.amock.util.Will;
import junit.framework.TestCase;
public class SimpleExampleTest extends TestCase {
private DummyClass dummyMock;
//private DummyInterface dummyMock;
public void setUp() {
//private constructor need A.mock()
//and when you use it you don't have to specify parameter even if constructor need parameter
dummyMock = mock(DummyClass.class);
// if it was public constructor
//dummyMock = new DummyClass();
// if it was interface
//dummyMock = mock(DummyInterface.class);
}
public void testSimple() {
new Story() {{
//Recording is done in this block.
//Record Method call
dummyMock.noReturn(3);
//Record Method call with expected return value;
a(dummyMock.returnThis(1)).ret(1);
//Record Method call with expected return value;
a(dummyMock.multiply(0,anyInt())).ret(1);
//Record Method call with expected expected calling times and expected Exception to throw;
a(dummyMock.devide(anyInt(),eq(0))).times(2).toss(new ArithmeticException());
//Record Method call with expected expected calling times;
dummyMock.noReturn(1);a().times(2);
//Record static method call with expected expected return value
call();a(DummyClass.staticReturnThis(1)).ret(1);
//Record constructor call with expected expected return value
call();a(new Integer(1)).ret(new Integer(3));
//Record static method call with expected expected return value
call();a(DummyClass.getInstance()).ret(dummyMock);
a(dummyMock.toString()).ret("dummy");
}};
dummyMock.noReturn(3);
assertEquals(1, dummyMock.returnThis(1));
assertEquals(1, dummyMock.multiply(0,7));
try {
dummyMock.devide(3,0);
fail("should not reach here");
} catch (ArithmeticException e) {}
try {
dummyMock.devide(5,0);
fail("should not reach here");
} catch (ArithmeticException e) {}
dummyMock.noReturn(1);
dummyMock.noReturn(1);
assertEquals(1, DummyClass.staticReturnThis(1));
assertEquals(3, new Integer(1).intValue());
assertEquals(dummyMock, DummyClass.getInstance());
assertEquals("dummy", dummyMock.toString());
}
public void testField() {
Object original = A.field(dummyMock, "privateFinal").get();
Object newOne = new Object();
A.field(dummyMock, "privateFinal").set(newOne);
Object changed = A.field(dummyMock, "privateFinal").get();
assertNotSame(original, changed);
assertEquals(newOne, changed);
}
public void testMethod() {
final my.amock.util.Method privateMethod = A.methodExact(dummyMock, "privateMethod", int.class);
new Story() {{
a(privateMethod.invoke(3)).ret(5);
}};
assertEquals(5, privateMethod.invoke(3));
}
public void testAssign() {
String a = "a";
String ab = "ab";
A.assign(a, ab);
assertEquals("ab", a);
}
}
Amock 9.5
With Amock, You can
- mock static method and constructor.
- mock private method.
- create mock instance of private constructor class, interface and of course normal class instance.
- create mock instance without any parameter input when class have only parameter constructor.
- access private method and attribute easily.
- use argument checker (argument matcher 'eq(). any()...') only where it is needed.
...
All you need to do is install aspectj eviroment and add Amock library to aspect path and class path.
It is FREE !
Download here
http://www.box.net/shared/2r5pkpkzpi
Sample code.
- mock static method and constructor.
- mock private method.
- create mock instance of private constructor class, interface and of course normal class instance.
- create mock instance without any parameter input when class have only parameter constructor.
- access private method and attribute easily.
- use argument checker (argument matcher 'eq(). any()...') only where it is needed.
...
All you need to do is install aspectj eviroment and add Amock library to aspect path and class path.
It is FREE !
Download here
http://www.box.net/shared/2r5pkpkzpi
Sample code.
package my.amock.example;
import static my.amock.util.Will.*;
import static my.amock.util.A.*;
import static my.amock.check.Check.*;
import my.amock.bracket.Story;
import my.amock.util.A;
import my.amock.util.Will;
import junit.framework.TestCase;
public class SimpleExampleTest extends TestCase {
private DummyClass dummyMock;
//private DummyInterface dummyMock;
public void setUp() {
//private constructor need A.mock()
//and when you use it you don't have to specify parameter even if constructor need parameter
dummyMock = mock(DummyClass.class);
// if it was public constructor
//dummyMock = new DummyClass();
// if it was interface
// dummyMock = A.mock(DummyInterface.class);
}
public void testSimple() {
new Story() {{
//Recording is done in this block.
//Record Method call
dummyMock.noReturn(3);
//Record Method call with expected return value;
a(dummyMock.returnThis(1)).ret(1);
//Record Method call with expected return value;
a(dummyMock.multiply(0,anyInt())).ret(1);
//Record Method call with expected expected calling times and expected Exception to
throw;
a(dummyMock.devide(anyInt(),0)).times(2).toss(new ArithmeticException());
//Record Method call with expected expected calling times;
dummyMock.noReturn(1);a().times(2);
//Record static method call with expected expected return value
call();a(DummyClass.staticReturnThis(1)).ret(1);
//Record constructor call with expected expected return value
call();a(new Integer(1)).ret(new Integer(3));
//Record static method call with expected expected return value
call();a(DummyClass.getInstance()).ret(dummyMock);
}};
dummyMock.noReturn(3);
assertEquals(1, dummyMock.returnThis(1));
assertEquals(1, dummyMock.multiply(0,7));
try {
dummyMock.devide(3,0);
fail("should not reach here");
} catch (ArithmeticException e) {}
try {
dummyMock.devide(5,0);
fail("should not reach here");
} catch (ArithmeticException e) {}
dummyMock.noReturn(1);
dummyMock.noReturn(1);
assertEquals(1, DummyClass.staticReturnThis(1));
assertEquals(3, new Integer(1).intValue());
assertEquals(dummyMock, DummyClass.getInstance());
}
public void testField() {
Object original = A.field(dummyMock, "privateFinal").get();
Object newOne = new Object();
A.field(dummyMock, "privateFinal").set(newOne);
Object changed = A.field(dummyMock, "privateFinal").get();
assertNotSame(original, changed);
assertEquals(newOne, changed);
}
public void testMethod() {
final my.amock.util.Method privateMethod = A.methodExact(dummyMock, "privateMethod",
int.class);
new Story() {{
a(privateMethod.invoke(3)).ret(5);
}};
assertEquals(5, privateMethod.invoke(3));
}
public void testAssign() {
String a = "a";
String ab = "ab";
A.assign(a, ab);
assertEquals("ab", a);
}
}
Tuesday, February 20, 2007
Amock 0.9
This is 0.9 version of AOP based Mock.
Changes
Now can record Exception throwing.
Easy use of comparators.
Changes
Now can record Exception throwing.
Easy use of comparators.
Sample code: SimpleTest.java
package package test;
import static my.amock.util.Will.call;
import static my.amock.util.Will.ret;
import junit.framework.TestCase;
import my.amock.bracket.Mock;
import my.amock.bracket.Story;
import my.amock.check.Check;
import my.amock.util.A;
class DivideAndDivide {
public int ADivideBDivideC(int a, int b, int c) {
DividerSingleton divider = DividerSingleton.getInstance();
int i = divider.divide(a, b);
return divider.divide(i, c);
}
}
class DividerSingleton {
private DividerSingleton() {
}
public static DividerSingleton getInstance() {
// Not yet implemented
return null;
}
public int divide(int a, int b) throws ArithmeticException {
// Not yet implemented
return 0;
}
}
class Dummy {
public void inBoolean(boolean b) {
}
public void inInt(int i) {
}
public void inObject(Object o) {
}
}
public class SimpleTest extends TestCase {
DividerSingleton divider;// mock
DivideAndDivide divideAndDivide;// test target
Dummy dummyMock;
protected void setUp() throws Exception {
// create mock object
new Mock() {{
// private constructor need constructorExact()
divider = A.constructorExact(DividerSingleton.class).invoke();
// if it was public constructor
// divider = new DividerSingleton();
// if it was interface
// divider = A.mock(DividerSingleton.class);
}};
//create normal object
divideAndDivide = new DivideAndDivide();
}
public void testAdderSingleton() {
//recording scenario
new Story() {{
// One time call record for static method with return value
// Only static method need call() method;
//Will.call();
call(divider); DividerSingleton.getInstance();
//Will.ret();
ret(2); divider.divide(4, 2);
ret(1); divider.divide(2, 2);
}};
//test target object
int returnValue = divideAndDivide.ADivideBDivideC(4, 2, 2);
assertEquals(1, returnValue);
}
public void testEqAnyIsNull() {
dummyMock = new Dummy();
//recording scenario
new Story() {{
dummyMock.inInt(Check.anyInt());
dummyMock.inBoolean(Check.anyBoolean());
dummyMock.inObject(Check.any(Dummy.class));
dummyMock.inObject(Check.isNull(Object.class));
dummyMock.inObject(Check.notNull(Object.class));
dummyMock.inObject(Check.isA(Object.class));
}};
dummyMock.inInt(20);
dummyMock.inBoolean(false);
dummyMock.inObject(new Dummy());
dummyMock.inObject(null);
dummyMock.inObject(new Object());
dummyMock.inObject(new Dummy());
}
}
Saturday, August 26, 2006
Amock 0.9 beta
This is beta version of AOP based Mock.
Amock is AOP based Mock library. It currently support only 1.5version of JDK but it will soon support 1.4 version of JDK. And I hope to Implement Amock on C# and C++. For now, only java version is available. Source code will be available soon.
Pros
You can record even a static method call.
You can reduce your typing
Cons
Weaving time is slow
Aspectj can not handle Checked Exception. So, Needs manual works to throw checked exception on static method.
Prerequisite
JDK 1.5 version
Eclipse 3.2
AJDT 1.4.0
Download Amock libarary and documentation from
http://www.box.net/public/i3dxv1ba8g#main
and CGlib no dependency 2.1_3
http://prdownloads.sourceforge.net/cglib/cglib-nodep-2.1_3.jar?download
To use this libary
First change project to AspectJ project.
Second, Add 'Amock-bin.jar' in your AspectJ Aspect path.
Third, Add 'Amock-bin.jar' and 'cglib-nodep-2.1_3.jar' in your Class path.
Now you ready to use Amock.
To throw Checked Exception on static method, Define ExceptionDefineAspect.aj on Aspectj Path
(package does not mater. Bold should be changed to exception you want to throw)
package my.amock.core;
import java.io.IOException;
public aspect ExceptionDefineAspect extends CommonAspect {
Object around() throws IOException : call(* *(..) throws IOException)
&& notInMockPackage()
&& if(isMockThrow(IOException.class, thisJoinPoint)) {
throw (IOException) getThrowable(thisJoinPoint);
}
}
Sample code: SimpleTest.java
package my.amock.example;
import my.amock.bracket.Mock;
import my.amock.bracket.Story;
import my.amock.util.A;
import junit.framework.TestCase;
import static my.amock.util.Will.*;
class DivideAndDivide {
public int ADivideBDivideC(int a, int b, int c) {
DividerSingleton divider = DividerSingleton.getInstance();
int i = divider.divide(a, b);
return divider.divide(i, c);
}
}
class DividerSingleton {
private DividerSingleton() {
}
public static DividerSingleton getInstance() {
// Not yet implemented
return null;
}
public int divide(int a, int b) throws ArithmeticException {
// Not yet implemented
return 0;
}
}
public class SimpleTest extends TestCase {
DividerSingleton divider;// mock
DivideAndDivide divideAndDivide;// test target
protected void setUp() throws Exception {
// create mock object
new Mock() {{
// private constructor need constructorExact()
divider = A.constructorExact(DividerSingleton.class).invoke();
// if it was public constructor
// divider = new DividerSingleton();
// if it was interface
// divider = A.mock(DividerSingleton.class);
}};
//create normal object
divideAndDivide = new DivideAndDivide();
}
public void testAdderSingleton() {
//recording scenario
new Story() {{
// One time call record for static method with return value
// Only static method need call() method;
//Will.call();
call(divider); DividerSingleton.getInstance();
//Will.ret();
ret(2); divider.divide(4, 2);
ret(1); divider.divide(2, 2);
}};
//test target object
int returnValue = divideAndDivide.ADivideBDivideC(4, 2, 2);
assertEquals(1, returnValue);
}
}
Sample code: SampleTest.java
package my.amock.example;
import java.util.Comparator;
import my.amock.bracket.Story;
import my.amock.util.A;
import my.amock.util.Mock;
import my.amock.util.NotMock;
import my.amock.util.NotStory;
import my.amock.util.Will;
import junit.framework.TestCase;
class Dummy {
private int privateField = 1;
private int privateMethod() {
return privateField;
}
public static int staticMethod(String arg1, int arg2) {
return 2;
}
public Character aMethod(String arg1, Long arg2) {
return 't';
}
public int aMethodTwo(String arg1, int arg2) {
return 1;// privateMethod();
}
}
/**
* This class show how to use Amock (It is not an example of how to use a mock
* in unit test) In other word, it just show you functionality of Amock.
*
* @author Jonghyun Yoon
*
*/
public class SampleTest extends TestCase {
Comparator alwaysTrueComparator = new Comparator() {
public int compare(Object o1, Object o2) {
return 0;
}
public boolean equals(Object obj) {
return super.equals(obj);
}
};
// It is a mock object because it is end with 'mock'
private Dummy dummyMock;
// It is not a mock object because @NotMock is attached
@NotMock
private Dummy notAMock;
// It is a mock object because @Mock is attached
@Mock
private Dummy mockDummy;
// It will be a mock object because mockBlock is instantiated in Mock block
private Dummy mockBlock;
protected void setUp() throws Exception {
// If an instance is created in the mock block then it will be a mock
// object.
new my.amock.bracket.Mock() {
{
mockBlock = new Dummy();
}
};
dummyMock = new Dummy();
notAMock = new Dummy();
mockDummy = new Dummy();
}
public void testBockStory() {
// In Story block, All mock method calling will be recorded.
new Story() {
{
dummyMock.aMethod("test", 1L);
// Can use static import like
// ret('x'); mockDummy.aMethod("test", 2L);
Will.ret('x');
mockDummy.aMethod("test", 2L);
// Can specify comparator.
Will.with(null, alwaysTrueComparator);
mockBlock.aMethod("test", 2L);
// Will.call() can use to record static method.
Will.call();
Dummy.staticMethod("test", 1);
}
};
assertEquals(Character.valueOf(Character.MIN_VALUE), dummyMock.aMethod(
"test", 1L));
assertEquals(1, notAMock.aMethodTwo(null, 0));
assertEquals(Character.valueOf('x'), mockDummy.aMethod("test", 2L));
mockBlock.aMethod("test", 0L);
assertEquals(Integer.valueOf(1), (Integer) A.field(notAMock,
"privateField").get());
assertEquals(Integer.valueOf(1), (Integer) A.methodExact(notAMock,
"privateMethod").invoke());
try {
Dummy.staticMethod("test", 2);
} catch (Throwable t) {
return;
}
fail("Should not reach here");
}
// Method end with 'Story' will become Story block.
public void aStory() {
// System.out.println("Story enter");
dummyMock.aMethod("test", 1L);
}
// This is Story block because @Story is attached.
@my.amock.util.Story
public void storyTwo() {
// Can use static import
Will.ret('x');
mockDummy.aMethod("test", 2L);
}
// This is not Story block because @NotStory is attached.
@NotStory
public void notAStory() {
try {
// There is no recorded action, So it will throw Exception.
mockBlock.aMethod("test", 2L);
} catch (Throwable t) {
return;
}
fail("Should not reach here");
}
public void testStoryMethodStoryEnd() {
aStory();
storyTwo();
notAStory();
// One Time Record
Will.call(1);
Dummy.staticMethod("test", 1);
assertEquals(Character.valueOf(Character.MIN_VALUE), dummyMock.aMethod(
"test", 1L));
assertEquals(1, notAMock.aMethodTwo(null, 0));
assertEquals(Character.valueOf('x'), mockDummy.aMethod("test", 2L));
assertEquals(Integer.valueOf(1), (Integer) A.field(notAMock,
"privateField").get());
assertEquals(Integer.valueOf(1), (Integer) A.methodExact(notAMock,
"privateMethod").invoke());
assertEquals(Integer.valueOf(1), (Integer) Dummy
.staticMethod("test", 1));
}
}