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

    主站蜘蛛池模板: 亚洲精品乱码久久久久久蜜桃图片 | av免费不卡国产观看| 久久精品免费观看| 亚洲午夜精品第一区二区8050| 亚洲五月综合网色九月色| 亚洲一区二区三区免费在线观看| 美女被免费视频网站a国产| 国产裸模视频免费区无码| 亚洲一级特黄特黄的大片 | 毛片免费在线观看网站| 亚洲人成影院77777| 亚洲成AV人片在WWW| 全免费a级毛片免费**视频| 亚洲日韩AV无码一区二区三区人| 野花高清在线观看免费完整版中文 | 最近中文字幕无吗高清免费视频| 亚洲av永久无码嘿嘿嘿| 97人伦色伦成人免费视频| 国产亚洲午夜高清国产拍精品| 久久久久亚洲Av无码专| 蜜桃AV无码免费看永久| 中文无码亚洲精品字幕| 日本人成在线视频免费播放| 激情内射亚洲一区二区三区| 日韩国产免费一区二区三区| 九月丁香婷婷亚洲综合色| 99视频精品全部免费观看| 亚洲国产精品久久网午夜| 天天拍拍天天爽免费视频| 亚洲视频2020| 成人片黄网站色大片免费观看cn| 成人免费淫片在线费观看| 朝桐光亚洲专区在线中文字幕| 亚洲国产日韩在线观频| 99免费在线观看视频| 2020亚洲男人天堂精品| 免费一级国产生活片| 免费无码作爱视频| 国产av无码专区亚洲av果冻传媒 | 亚洲人成网站色在线观看| jjzz亚洲亚洲女人|