熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

利用spring2.5和Reflection簡化測試中的mock[3]

2013-11-23 20:44:39  來源: Java開源技術 

  < bean id=Helloword class=Helloworld autowire=byType> 現在看上去是不是好多了?嗯對象間的依賴關系和mock對象的創建都由 Spring 來替我們維護再也不用費心了不過reset/verify 是不是還是看上去那麼舒服?我們觀察一下通常為了簡化對 mock 對象的驗證我們對 Test 類中使用到的 mock 對象都是一起reset/replay /verify要是能有resetAll()/replayAll()/verifyAll()方法就好了也省得不同的 Test 類寫一大串對不同的 Mock 對象驗證的方法OK這時候我們就要借助 Reflection 來完成這項任務了通過 Reflection 得到 Test 類中所有加上 @Autowired 聲明的成員變量驗證它們是不是由代理或者字節碼增強從而得到該 Test 類的所有由 Spring 創建的 mock 對象進行 reset/replay/verify

  根據這個思路我們引入這樣一個 mock 測試的Helper類

import static orgeasymockEasyMock*;

final class MockTestHelper {

    public static void resetAll(Object testObject) {
        reset(getDeclaredMockedFields(testObject));
    }

    public static void verifyAll(Object testObject) {
        verify(getDeclaredMockedFields(testObject));
    }

    public static void replayAll(Object testObject) {
        replay(getDeclaredMockedFields(testObject));
    }

    private static Object[] getDeclaredMockedFields(Object testObject) {
        Field[] declaredFields = testObjectgetClass()getDeclaredFields();
        List declaredMockedFields = new ArrayList();
        for (Field field : declaredFields) {
            if (fieldisAnnotationPresent(Autowiredclass)) {
                boolean isAccessible = fieldisAccessible();
                try {
                    fieldsetAccessible(true);
                    Object value = fieldget(testObject);
                    if (isClassProxy(valuegetClass())) {
                        declaredMockedFieldsadd(value);
                    }
                } catch (IllegalAccessException e) {
                    eprintStackTrace();
                }
                finally {
                    fieldsetAccessible(isAccessible);
                }
            }
        }
        return declaredMockedFieldstoArray();
    }

    private static boolean isClassProxy(Class clazz) {
        String className = clazzgetName();
        return classNamecontains($Proxy) || classNamecontains($$EnhancerByCGLIB$$);
    }

}

  好了有了這麼一個 Helper 類寫 mock 對象的Test 類就簡單了許多還是以上面的例子為例經過這麼一重構變成如下

  這樣看起來就好多了以後不管在 Test 類裡面添加多少個 Test 類需要的 mock 對象我們都不需要再修改對 mock 對象的驗證了Helper類會自動< bean id=Helloword class=Helloworld autowire=byType>幫我們完成所有的工作& ltbr />綜上所述使用Spring裡面引入的 Test Cntext 和 annotations 的確幫助我們減輕了大量的測試代碼量而且讓我們的 Test 類更加POJO更易於讓人理解其職責成為對 feature 的 specification而 Reflection的小技巧則能很方便的改進原來代碼中不夠動態的地方進一步簡化代碼量和維護難度當然我們可以看到即使這樣代碼裡面還是有不少resetAll/replayAll/verifyAll的地方作為 mock 框架帶來的一些約束我們沒有辦法來省略這裡推薦一種新的 mock 框架—— mockito是有我的外國同事開發的它不僅把mockstubspy等double的概念區分更清楚而且讓我們的 mock 測試更易寫更易讀

[]  []  []  


From:http://tw.wingwit.com/Article/program/Java/ky/201311/29008.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.