利用h2database和easymock轻松不依赖环境单元测试(rose等spring环境万能)
以下内容由 [五四陈科学院]提供
前言
写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定义为:
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>2.5.6</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <version>1.3.163</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymockclassextension</artifactId>
- <version>2.4</version>
- <scope>test</scope>
- </dependency>
基础配置与schema.sql准备
在test/resources下我们需要两个关键的文件:applicationContext.xml 与 schema.sql
applicationContext.xml定义了test执行时扫描的情况,同正常运行时使用的配置大同小异。不同在于需要替换db定义中的mysql driver为h2的driver,关键部分:
- <property name="driverClassName" value="org.h2.Driver"></property>
- <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,代码如下:
- Statement st = conn.createStatement();
- st.execute("drop all objects;");
- st.execute("runscript from '" + new DefaultResourceLoader().getResource("schema.sql").getURL().toString() + "'");
- st.close();
而如果是spring/rose环境,则可以再加载上context.xml文件,代码如下:
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = "classpath:applicationContext.xml")
- public class TestDAOTest {
然后就开始写测试代码:
- @Test
- public void getTestTest() {
- com.chen.model.Test t = testDAO.getTest();
- Assert.assertEquals(111, t.getId());
- }
easymock的代码示例
easymock以前也提到过,这里再提一次: http://www.54chen.com/java-ee/spring-easymock-tutorial.html
- @Test
- public void getTestTest() {
- com.chen.model.Test t = new com.chen.model.Test();
- t.setId(1111);
- t.setMsg("adfadf");
- TestDAO testDAO = EasyMock.createMock("testDAO", TestDAO.class);
- EasyMock.expect(testDAO.getTest()).andReturn(t);
- EasyMock.replay(testDAO);
- ReflectionTestUtils.setField(service, "testDAO", testDAO, TestDAO.class);
- t = service.getTest();
- // 确信使用了mock
- EasyMock.verify(testDAO);
- Assert.assertEquals(1111, t.getId());
- }
mock其他东西以此类推。
后序
至此,已经可以mock一切了,你还有什么理由不写test case呢?
本文完整代码可以在 https://github.com/XiaoMi/rose 下载到。
想快点找到作者也可以到Twitter上留言: @54chen
或者你懒得带梯子上墙,请到新浪微博: @54chen