文/陈刚 from
http://blog.chengang.com.cn
有一个需要被测试的类如下:
问题:如果要测试getView方法该怎么办呢?
显然由于此方法依赖于factory(XmlBeanFactory ),XmlBeanFactory 内含有比较复杂的逻辑,而且还要读取XML文件,这导致getView不可能被单独测试(一个单元测试的要点:简单独立,一次只测试一个类)。为了让ViewManager能剔除掉XmlBeanFactory,而被单独测试,我们需要做一些改变--让XmlBeanFactory由外界注入,这样就可以写一个逻辑简单的Mock类来替代XmlBeanFactory,实现ViewManager的单独测试。具体实现的方法是加一个构造函数,让XmlBeanFactory可以通过构造函数注入,当然为了保持原有代码的兼容性,默认的factory也不可少。代码如下:
测试的代码如下:
有一个需要被测试的类如下:
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();
}
}
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();
}
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;
}
}
}
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;
}
}
}