<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    thinking

    one platform thousands thinking

    Mocking Static Calls

    How can you test methods that contain static method calls? This is a question we're facing at the moment while working on an application of which parts have been written by another development team. In order to gain insight into functionality and quality of the codebase, we are writing JUnit tests. But a lot of the code is dependent on either the JSF FacesContext or the Spring ApplicationContext being available.

    It is however impossible to mock static method calls like FacesContext.getCurrentInstance(). So how do we go around testing these calls out of container? We've thought up three different approaches, but each has its pros and cons. Let us first take a look at these three approaches...

    1. Extract method
    Introduce a method in each class that looks like the following:

     
    protected FacesContext getFacesContext() {
    return FacesContext.getCurrentInstance();
    }
     

    This can be easily mocked out in your test by creating the class with an overridden method, as follows:

     
    FacesContext mockContext = EasyMock.createMock(FacesContext.class);
    new MyObjectUnderTest() {
    protected FacesContext getFacesContext() {
    return mockContext;
    }
    }
     

    Pros

    • Easy to refactor using extract method

    Cons

    • Lots of code duplication

    2. Static Helper
    Our second option is to introduce a static helper class which has the following implementation:

     
    public class FacesContextHelper {
    private static FacesContext context;
     
    public static FacesContext getCurrentFacesContext() {
    return context != null ? context : FacesContext.getCurrentInstance();
    }
     
    public static void setFacesContext(FacesContext facesContext) {
    context = facesContext;
    }
     
    public static void reset() {
    context = null;
    }
    }
     

    Now in a testclass we can just write down the following line to mock out the FacesContext:

     
    FacesContextHelper.setFacesContext(EasyMock.createMock(FacesContext.class));
     

    Pros

    • No real painful code-duplication
    • Easy to do search-replace to convert all calls to FacesContext.getCurrentInstance() to FacesContextHelper.getCurrentFacesContext().

    Cons

    • Never forget to call reset() in the teardown of your test to prevent another test from picking up your mock.
    • Doesn't feel right to write static setter methods in your code just to enable testing it. Not an OO approach?

    3. OO Helper class
    Our third and last option is to introduce an interface and implementation of the FacesContextHelper:

     
    public interface FacesContextHelper {
    FacesContext getCurrentFacesContext();
    }
     
    public class FacesContextHelperImpl implements FacesContextHelper {
    public FacesContext getCurrentFacesContext() {
    return FacesContext.getCurrentInstance();
    }
    }
     

    We now need to introduce an instance of the FacesContextHelperImpl to each class. For this example, we will use a package protected variable in each class. It is of course also possible to use a setter method. For our test cases we now need to introduce a new FacesContextHelper:

     
    public class MockFacesContextHelper implements FacesContextHelper {
    private FacesContext mockContext;
     
    public MockFacesContextHelper(FacesContext mockContext) {
    this.mockContext = mockContext;
    }
     
    public FacesContext getCurrentFacesContext() {
    return this.mockContext;
    }
    }
     

    In our test cases we can now easily mock out the FacesContext again by setting the package protected field:

     
    someClazz.facesContextHelper = new MockFacesContextHelper(EasyMock.createMock(FacesContext.class));
     

    Pros

    • Feels more natural and OO than the static helper solution

    Cons

    • Need to introduce a new field to each and every class which needs the FacesContext mocked out.

    That's it. I myself am still doubting as to which method is the lesser evil, not one feels absolutely right. What do you think, which method do you consider better? Did I overlook another option perhaps?

    posted on 2010-02-25 09:12 lau 閱讀(344) 評論(0)  編輯  收藏 所屬分類: Unit Test

    主站蜘蛛池模板: 成在人线av无码免费高潮水| 亚洲国产欧美国产综合一区| www免费黄色网| 亚洲成a人片在线观看日本麻豆| 亚洲精华国产精华精华液网站| 精品国产精品久久一区免费式| 亚洲AV无码AV男人的天堂不卡| 免费毛片网站在线观看| 亚洲AV无码一区二区三区久久精品 | 亚洲国产精品丝袜在线观看| 亚洲av片在线观看| 亚洲精品tv久久久久久久久久| 一级特黄录像免费播放中文版| 亚洲中文字幕无码久久精品1| 中文字幕乱码一区二区免费| 亚洲人成在线播放网站岛国| 无码国产精品一区二区免费式影视 | 亚洲美女视频网站| 一二三四免费观看在线视频中文版 | 国产无遮挡色视频免费观看性色| 亚洲色偷拍另类无码专区| 久久久国产精品福利免费| 亚洲午夜国产精品| 亚洲成aⅴ人片久青草影院| 国产免费A∨在线播放| 亚洲日本中文字幕| 色吊丝最新永久免费观看网站| 免费无遮挡无码视频在线观看 | 7777久久亚洲中文字幕蜜桃| 久久精品女人天堂AV免费观看| 在线播放亚洲精品| 国产亚洲精品va在线| 亚洲综合免费视频| 深夜久久AAAAA级毛片免费看| 亚洲级αV无码毛片久久精品| 免费视频专区一国产盗摄| 特级毛片全部免费播放a一级| 亚洲五月六月丁香激情| 日本人护士免费xxxx视频| 国产免费爽爽视频在线观看| 亚洲不卡1卡2卡三卡2021麻豆|