天天看點

關于easymock

作為一個月薪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的入門學習

繼續閱讀