<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 閱讀(346) 評論(0)  編輯  收藏 所屬分類: Unit Test

    主站蜘蛛池模板: 亚洲欧洲日产v特级毛片| 亚洲午夜成人精品电影在线观看| 亚洲中文无码mv| 真人做人试看60分钟免费视频 | 狠狠综合亚洲综合亚洲色| 大学生一级毛片免费看| 久久狠狠爱亚洲综合影院| 老司机在线免费视频| 亚洲精品字幕在线观看| 成全动漫视频在线观看免费高清版下载| 国产亚洲美女精品久久久| 成人免费乱码大片A毛片| 久久亚洲国产午夜精品理论片 | 无码国产精品一区二区免费式直播| 亚洲欧洲日产国码二区首页| 野花高清在线电影观看免费视频| 狠狠色伊人亚洲综合网站色| 国产免费131美女视频| 特级aaaaaaaaa毛片免费视频| 30岁的女人韩剧免费观看| 亚洲日韩在线视频| 毛片免费在线播放| 免费无遮挡无码视频在线观看 | 日韩成全视频观看免费观看高清| 日韩欧美亚洲国产精品字幕久久久 | 日韩版码免费福利视频| 亚洲AV女人18毛片水真多| 在线亚洲精品自拍| 亚洲视频免费在线看| 日韩成人精品日本亚洲| 亚洲乱码日产一区三区| 男女免费观看在线爽爽爽视频| 久久亚洲中文无码咪咪爱| 亚洲色WWW成人永久网址| 两性刺激生活片免费视频| 成人免费网站久久久| 亚洲一本综合久久| 免费人成激情视频在线观看冫| 亚洲第一成年人网站| 又粗又硬又大又爽免费视频播放| 国产精品视频白浆免费视频|