<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无码网站大全| 妞干网在线免费视频| 国产亚洲美女精品久久久| 春暖花开亚洲性无区一区二区 | 国产一级一片免费播放| 亚洲日韩国产二区无码| 免费看美女被靠到爽| 豆国产96在线|亚洲| 亚洲国产精品毛片av不卡在线| 免费精品视频在线| 亚洲日韩国产一区二区三区| j8又粗又长又硬又爽免费视频| 国产亚洲?V无码?V男人的天堂 | 无码人妻精品中文字幕免费东京热| 亚洲福利一区二区精品秒拍| 久久久久久精品成人免费图片| 亚洲人成网站日本片| 精品免费久久久久久成人影院| 免费无码又爽又黄又刺激网站| 国产亚洲美日韩AV中文字幕无码成人 | 久久精品网站免费观看| 亚洲国产欧洲综合997久久| 亚洲精品国产电影| 秋霞人成在线观看免费视频| 亚洲免费在线视频观看| 四虎影视永久免费观看地址| 丝瓜app免费下载网址进入ios | 色欲色欲天天天www亚洲伊| 免费大香伊蕉在人线国产| 99久久婷婷免费国产综合精品| 精品亚洲成a人片在线观看| 成人毛片免费观看视频大全| 人人鲁免费播放视频人人香蕉| 亚洲精品免费视频| 在线观看无码的免费网站| 久久久WWW免费人成精品| 亚洲一区二区三区在线| 国产传媒在线观看视频免费观看| 久久er国产精品免费观看2| 亚洲中文字幕乱码AV波多JI| 亚洲综合无码精品一区二区三区|