服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

工欲善其事,必先利其器之easymock篇

 在做项目的时候,经常看见很多兄弟们在做一些无用功,其实,现在java语言已经形成了一个形形色色的生态圈,在这个生态圈里,有it巨鳄的ibm,有两头受气的sun,还有各种各样为我们提供工具的开源社区,如apache,eclipse,freshmeat,sourceforge,netbeans等。此外,j2se 5.0推出以后也为我们节省了不少工作。我们完全可以利用这些资源,节省很多为老板干活的时间,从而将有限的生命投入到无限的泡mm事业中去。
 
  闲言少叙,dingdang准备写个系列文章,讲述一些工具,api以及其背后的原理。兄弟抛块砖先,有玉的尽管砸过来,我闪
 
一,测试工具easymock
 
   在这个系列文章中以测试开始,把它作为我们这篇入门介绍文档的开头,不是偶然的,正如村上春树在《挪威的森林》里面说的那样,死并不是生的对立面,而是作为生的一部分而存在。测试也不是开发的对立面,而是作为开发的一部分而存在,我们总是在不断的写代码,单元测试,写代码,单元测试......作为单元测试的工具junit框架大家可能已经耳熟能详,martin fowler对它的评价是"never in the field of software development was so much owed by so many to so few lines of code"。一时aunit,bunit,仿效者无数。可谓武林至尊
   可是,仅仅junit是不够的。我们在做项目的时候就遇到了这样的场景:
  
  大米:终于写完代码了,可以上qq泡mm了.....
  dingdang:哦,写完了,给个测试用例先。
  大米:没法子给测试用例啊,我写的这个类要用到苞谷写的类耶
  dingdang去找苞谷:苞谷,你的代码怎么还没写完啊,搞的大米连单元测试都做不了。
  苞谷:不是我得错,苹果没有写完我需要的类
  苹果:也不是我得错,大米没有写完我需要的类
  dingdang:×※……%¥
 
  其实,这些类的依赖关系首先是违反了一个原则:the dependency inversion principle(依赖转置原则)
  抽象不应该依赖于细节,而细节应该依赖于抽象。
  高层的模块不应该依赖于底层的模块,它们都应该依赖于抽象
  通俗一点的说,就是,我们在做java设计的时候,应该尽可能的依赖于接口而不是实现。
  dingdang嘿嘿奸笑两声:大米啊,我们修改一下设计吧,把我们的设计refactoring一下。
  三分钟后,大米说:dingdang啊,改成接口还是没法子测试啊。
  dingdang再次狂笑:哈哈,倚天不出,谁与争锋,看我的easymock!!!!!
 
      easymock软件安装很简单,先到以下地址下载一个最新的zip包: www.easymock.org,下载完以后将easymock.jar包加到你的系统的classpath环境变量中,对于ide环境,对于需要用到的junit的项目增加到lib中,不同的ide有不同的设置,这里不多讲。
      easymock的长处在于模拟接口的行为,(新版的easymock利用cglib据说也可以模拟类的行为,没有试用过:p)假如你有一个类helloworld,依赖接口dependentinterface,easymock就可以在运行的时候生成dependentinterface接口的实现。这些实现的行为和返回值都可以在单元测试代码里面指定。我们用一个junit例子来进行说明
     首先,需要导入mockcontrol类,如下样例中的第一步,
     然后选择一个接口,创建这个接口的模拟实例,如以下样例中的第二步。
     最后,先模拟一下你希望的类的行为,如返回值等,调用mockcontrol类的replay方法:
   
     import junit.framework.*;
     import org.easymock.mockcontrol;// step 1
     interface dependentinterface{
        public string sayhello();
     }
    class helloworld{
         private dependentinterface dp_;
         public helloworld(dependentinterface dp){
           dp_ = dp;
       }
       public string sayanotherhello(){
           return dp_.sayhello();
        }
    }
    public class testhelloworld extends testcase {
        private helloworld helloworld_ = null;
        private mockcontrol control_;
        private dependentinterface dp_;
        protected void setup() throws exception {
            super.setup();
            control_ = mockcontrol.createcontrol(dependentinterface.class);//step 2
            dp_ =(dependentinterface)control_.getmock();//step 2
            helloworld_ = new helloworld(dp_);
         }
       protected void teardown() throws exception {
            helloworld_ = null;
            super.teardown();
         } 
      public void testsayhello() {
          dp_.sayhello();//step 3
          control_.setreturnvalue("hello");//step 3
          control_.replay();//step 3
          string actualreturn = helloworld_.sayanotherhello();
           assertequals(actualreturn,"hello");
       
        }
     }


   easymock本身的文档写得很好,大家看看就会了,最重要的是依赖转置的思想和测试驱动的方法。
   
   dingdang争取下一篇文章剖析easymock的源代码,解释java的dynamic proxy的原理 
  

扫描关注微信公众号