54 CHEN

利用h2database和easymock轻松不依赖环境单元测试(rose等spring环境万能)

h2database,easymock 前言 写java时间久了,慢慢就变得自信了,也可能是变得懒了,或者是项目进度的原因,test case越写越少,越来越不写了。
还有一个很大的原因是,DB环境不好搞,老是有垃圾数据,依赖的东西太多,有memcache、有别人的服务,等等等等,都是没有test case良好的理由。

下面将以rose环境下,使用easy mock搞写第三方依赖和h2database搞写DB环境为例子,简单讲述如何轻松测试。

完整代码可以在 https://github.com/XiaoMi/rose 下载到。

依赖的包介绍 spring-test:提供一些基础的spring环境的支持,如果你不是spring环境,可能不需要。
h2:一个内存数据库,使用它的原因是,我们的业务大多数时候使用的都是mysql,而h2有一个mysql模式,可以支持绝大多数的mysql的SQL语句。
easymock:以前在五四陈科学院提到过的利器,用来模拟各种调用的工具。

pom定义为:

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-test</artifactId>
  4. <version>2.5.6</version>
  5. <scope>test</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.h2database</groupId>
  9. <artifactId>h2</artifactId>
  10. <version>1.3.163</version>
  11. <scope>test</scope>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.easymock</groupId>
  15. <artifactId>easymockclassextension</artifactId>
  16. <version>2.4</version>
  17. <scope>test</scope>
  18. </dependency>

基础配置与schema.sql准备 在test/resources下我们需要两个关键的文件:applicationContext.xml 与 schema.sql

applicationContext.xml定义了test执行时扫描的情况,同正常运行时使用的配置大同小异。不同在于需要替换db定义中的mysql driver为h2的driver,关键部分:

  1. <property name=“driverClassName” value=“org.h2.Driver”></property>
  2. <property name=“url” value=“jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1”></property>

而schema.sql文件定义了初始化的表结构,这个文件的出现是因为h2与mysql还是有一定的语法区别的,不过在我的使用过程中,基本上只有create table的那个引擎声明是不支持的,所以喽,干掉先。

H2下的DAO的Test的代码示例 在test case的初始化状态里需要导入schema.sql,代码如下:

  1. Statement st = conn.createStatement();
  2. st.execute(“drop all objects;");
  3. st.execute(“runscript from ‘” + new DefaultResourceLoader().getResource(“schema.sql”).getURL().toString() + “'");
  4. st.close();

而如果是spring/rose环境,则可以再加载上context.xml文件,代码如下:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = “classpath:applicationContext.xml”)
  3. public class TestDAOTest {

然后就开始写测试代码:

  1. @Test

  2. public void getTestTest() {

  3. com.chen.model.Test t = testDAO.getTest();

  4. Assert.assertEquals(111, t.getId());

  5. }

easymock的代码示例

easymock以前也提到过,这里再提一次:http://www.54chen.com/java-ee/spring-easymock-tutorial.html

  1. @Test
  2. public void getTestTest() {
  3. com.chen.model.Test t = new com.chen.model.Test();
  4. t.setId(1111);
  5. t.setMsg(“adfadf”);
  6. TestDAO testDAO = EasyMock.createMock(“testDAO”, TestDAO.class);
  7. EasyMock.expect(testDAO.getTest()).andReturn(t);
  8. EasyMock.replay(testDAO);
  9. ReflectionTestUtils.setField(service, “testDAO”, testDAO, TestDAO.class);
  10. t = service.getTest();
  11. // 确信使用了mock
  12. EasyMock.verify(testDAO);
  13. Assert.assertEquals(1111, t.getId());
  14. }

mock其他东西以此类推。

后序 至此,已经可以mock一切了,你还有什么理由不写test case呢?
本文完整代码可以在 https://github.com/XiaoMi/rose 下载到。

原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]

Posted by 54chen java