利用IoC模式使类更易于测试

文/陈刚 from  http://blog.chengang.com.cn   

有一个需要被测试的类如下:

public  class ViewManager {
     private  static XmlBeanFactory factory = Context.getInstance().getXmlBeanFactory();

     public View getView(String viewId) {
        List<ViewBean> list = factory.getViews();
         for (ViewBean bean : list) {
             if (bean.getId().equals(viewId))
                 return bean.getView();
        }
         return  new NullComposite();
    }


问题:如果要测试getView方法该怎么办呢?

显然由于此方法依赖于factory(XmlBeanFactory ),XmlBeanFactory 内含有比较复杂的逻辑,而且还要读取XML文件,这导致getView不可能被单独测试(一个单元测试的要点:简单独立,一次只测试一个类)。为了让ViewManager能剔除掉XmlBeanFactory,而被单独测试,我们需要做一些改变--让XmlBeanFactory由外界注入,这样就可以写一个逻辑简单的Mock类来替代XmlBeanFactory,实现ViewManager的单独测试。具体实现的方法是加一个构造函数,让XmlBeanFactory可以通过构造函数注入,当然为了保持原有代码的兼容性,默认的factory也不可少。代码如下:

public  class ViewManager {
     private  static XmlBeanFactory factory;

     public ViewManager() {
        factory = Context.getInstance().getXmlBeanFactory(); // 默认的factory
    }

     public ViewManager(XmlBeanFactory factory) { // 注入的factory
         this.factory = factory;
    }

     public View getView(String viewId) {
        List<ViewBean> list = factory.getViews();
         for (ViewBean bean : list) {
             if (bean.getId().equals(viewId))
                 return bean.getView();
        }
         return  new NullComposite();
    }

测试的代码如下:

public  class TestViewManager  extends TestCase {
     private ViewManager viewManager;

    @Override
     protected  void setUp()  throws Exception {
         super.setUp();
        viewManager =  new ViewManager( new MockXmlBeanFactory());
    }

     public  void testGetView() {
        View v = viewManager.getView("viewId002");
        assertEquals("viewId002", v.getViewId());
        assertEquals(CustomView. class, v.getClass());
    }

     public  void testGetViewByNoneId() {
        View v = viewManager.getView("abc");
        assertEquals("abc", v.getViewId());
        assertEquals(NullComposite. class, v.getClass());
    }

     private  static  class MockXmlBeanFactory  extends XmlBeanFactory { //XmlBeanFactory 的Mock类

         public List<ViewBean> getViews() {
            List<ViewBean> views =  new ArrayList<ViewBean>();
            views.add( new CustomViewBean("viewId001", NullComposite. class.getName()));
            views.add( new CustomViewBean("viewId002", CustomView. class.getName()));
             return views;
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值