H2是一个使用Java实现的内存内存数据库,支持标准的SQL语法,支持大部分的MySQL语法和函数,很适合依赖关系型数据库(比如MySQL, SQL Server, Oracle等)的单元测试。(本文Spring + MySQL作为项目框架)
maven配置文件及spring配置文件,比如applicationContext.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
<scope>test</scope>
</dependency>
applicationContext.xml
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
unit-test.xml
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
</bean>
unit-test.xml
<jdbc:initialize-database data-source="ds">
<jdbc:script location="classpath:db-initial.sql"/>
</jdbc:initialize-database>
db-initial.sql
SET MODE=MySQL;
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE `t_chat` (
`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID序列,自增',
`fquestion` varchar(500) DEFAULT NULL COMMENT '问题',
`fanswer` varchar(2000) DEFAULT NULL COMMENT '答案',
`feditState` char(1) DEFAULT NULL COMMENT '0:未编辑,1:已编辑',
`favailable` smallint(6) DEFAULT '0' COMMENT '审核状态&删除状态(-1:已删除,0:审核中,1:通过,2:退回)',
`fcreateTime` datetime DEFAULT NULL COMMENT '该问答创建时间',
`feditTime` datetime DEFAULT NULL COMMENT '更新/编辑时间',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
配置完成之后,就可以愉快地写依赖数据库的单元测试了。 下面代码以spock作为单元测试框架为例,抛开given/when/then这种语句快,groovy代码和Java代码基本是一致的
@ContextConfiguration("classpath:unit-test.xml")
@Transactional
class CharDaoTest extends Specification {
@Resource
private ChatDao chatDao
def "return empty list when there are no rows in db"() {
given:
Map<String, String> params = new HashMap<>()
when:
final List<Chat> chats = chatDao.queryAllChatListByCondition(params)
then:
chats.size() == 0
}
def "return null when query a non-exists chat"() {
when:
final Chat chat = chatDao.queryAllChatListById("1")
then:
chat == null
}
}
注意添加注解:
Transactional
,不然单元测试之间会存在数据错误
ON UPDATE CURRENT_TIMESTAMP
ChatMapper.xml
<select id="queryTemplates" resultMap="templateMap" databaseId="h2">xxx</select>
<select id="queryTemplates" resultMap="templateMap" databaseId="mysql">xxx</select>
unit-test.xml
<bean id="vendorProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="MySQL">mysql</prop>
<prop key="H2">h2</prop>
</props>
</property>
</bean>
<bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
<property name="properties" ref="vendorProperties"/>
</bean>
NOT NULL
,但是插入的值是null,H2会自动转换为对应类型的默认值("", 0等) h2:convertinsertnulltozero @Component
class TestEnv {
@PostConstruct
private static void initEnv() {
Mode mode = Mode.getInstance("MYSQL")
mode.convertInsertNullToZero = false
}
}
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
factory-method="createWebServer" init-method="start" lazy-init="false">
<constructor-arg value="-web,-webAllowOthers,-webPort,11111" />
</bean>
然后浏览器打开http://localhost:11111
,![]
1521186192_13_w650_h388.png
1521186202_25_w852_h639.png
如果对你有一点帮助,麻烦为我点一个赞,如果没有帮助,也非常期待你的反馈