作為一個月薪3000的屌絲民工,今天也開始寫自己的微網誌了,打發一下dota之外的時光。接觸程式設計一年了,寫了一年的flex,雖然很是熟練,但是有啥用呢。新版flash的普及上不去,舊版的渲染太慢。還是改行好了。
今天下午看到了easymock。了解了他的使用方法後,很是驚奇,決定研究一下他的代碼
Print qm=EasyMock.createMock(Print.class);
我先定義了一個Print類,然後用createMock方法生成
createMock()的源碼是
public static <T> T createMock(final Class<T> toMock) {
return createControl().createMock(toMock);
}
createControl()方法生成了一個MocksControl對象
MocksControl中createMock()的實作是
public <T> T createMock(final String name, final Class<T> toMock, final ConstructorArgs constructorArgs,
final Method... mockedMethods) {
if (toMock.isInterface() && mockedMethods != null) {
throw new IllegalArgumentException("Partial mocking doesn't make sense for interface");
}
try {
//什麼都沒有做
state.assertRecordState();
final IProxyFactory proxyFactory = toMock.isInterface()
? interfaceProxyFactory
: getClassProxyFactory();
//toMock是傳入的類對象
return proxyFactory.createProxy(toMock, new ObjectMethodsFilter(toMock,
new MockInvocationHandler(this), name), mockedMethods, constructorArgs);
} catch (final RuntimeExceptionWrapper e) {
throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
}
}
這裡面生成的關鍵是使用proxyFactory.createProxy來根據類生成對象。proxyFactory根據toMock的類型使用不同的子類,
toMock是接口的話,使用JavaProxyFactory,他通過java自帶的反射機制類生成對象。
如果toMock不是接口,使用第三方jar包,如果是android的類(通過虛拟機來判斷),則使用dexmarker這個jar包生成對象;
否則使用objenesis這個jar包來生成對象。
在生成對象的同時,我們還加入了一個方法MockInvocationHandler;
它保證了在調用了這個對象的方法後,将目前的MocksControl對象設定為這個對象專用的MocksControl對象。
qm.printHello(strgetter);
EasyMock.expectLastCall().andReturn("nihao3").times(2);
這就是為什麼每次調用expectLastCall()時,能夠順利的操作他這個qm對應的MocksControl對象。
一個被生成的對象有一個專用的MocksControl對象來,來維護這個被生成對象的相關操作。
目前MocksControl的設定是通過LastControl.reportLastControl()來進行操作的。
他将MocksControl存儲在ThreadLocal中,ThreadLocal不是一個被我們經常使用的弱類型的資料存儲(類似map)。暫時還不明白這樣設計的巧妙之處。
LastControl.lastControl()方法則是擷取目前的MocksControl對象
今天看到這裡,打算明天繼續看看。全當作java的入門學習