Spring項目使用H2內存數據庫做單元測試

Spring 做單元測試

單元測試很重要,對於Spring項目,特別是測試Service層或者dao層的代碼時。需要驗證訪問數據庫的邏輯是否正確。測試Dao層的代碼兩種方式

使用外置數據庫

測試環境在外置數據庫裏面。這種情況下如果外置的數據庫裏面的數據變化了。就可能會導致單元測試跑不過。這種方式也是大家常用的但是不規範。

使用內存數據庫

內存數據庫也是一個數據庫,只不過是在內存裏面。每次程序啓動的時候,提前寫好SQL文件。把數據寫入,單元測試的時候訪問的就是內存數據庫裏面的數據。所以只要代碼的邏輯不出問題,每次訪問和測試都是可以通過的。所以這種方式是比較規範的。但是難度也是稍微會大一點。

H2內存數據庫介紹

H2是一個Java編寫的關係型數據庫,它可以被嵌入Java應用程序中使用,或者作爲一個單獨的數據庫服務器運行。
H2數據庫的前身是 HypersonicSQL,它的名字的含義是 Hypersonic2,但是它的代碼是從頭開始編寫的,沒有使用HypersonicSQL或者HSQLDB的代碼

Spring和H2結合使用

第一步,引入H2 的maven配置

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
            <scope>runtime</scope>
        </dependency>

第二步,添加創建數據庫和基本數據的SQL文件

h2-schema.sql

這裏放置你自己的數據的SQL文件

CREATE SCHEMA IF NOT EXISTS cmdb_docker;
CREATE TABLE `cmdb_docker`.`tb_publish_list` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `name` varchar(255) NOT NULL COMMENT '發佈單名稱',
  `project_name` varchar(255) NOT NULL COMMENT '應用名',
  `environment` varchar(255) NOT NULL COMMENT '環境信息,UAT或者線上',
  `status` varchar(255) NOT NULL COMMENT '發佈狀態',
  `image` varchar(255) NOT NULL COMMENT '鏡像信息',
  `type` varchar(255) NOT NULL COMMENT '發佈類型',
  `titan_id` bigint(20) DEFAULT NULL COMMENT '雲效id',
  `git_commit_id` varchar(255) DEFAULT NULL,
  `superior` varchar(255) NOT NULL COMMENT '無損,強制',
  `is_health_check` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否健康檢查',
  `is_gated_launch` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否灰度發佈',
  `is_traffic_publish` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否預發佈,流量調度',
  `ignore_direct_connection` tinyint(1) NOT NULL DEFAULT '0' COMMENT '無流量檢查時,是否忽略直接連接。',
  `flow_check_time_out` int(11) DEFAULT '0' COMMENT '無流量檢查超時時間,默認100s',
  `hcheck_online_interval` int(11) NOT NULL DEFAULT '0' COMMENT 'mainstay服務健康檢查與上線間隔,默認0,不超過120s',
  `publish_interval` int(11) NOT NULL COMMENT '發佈間隔時間',
  `publish_instance` int(11) NOT NULL COMMENT '發佈實例數',
  `old_version` varchar(255) DEFAULT NULL COMMENT '發佈前的版本',
  `new_version` varchar(255) DEFAULT NULL COMMENT '發佈後版本',
  `offline_or_not` tinyint(1) NOT NULL COMMENT '是否下線',
  `online_or_not` tinyint(1) NOT NULL COMMENT '是否上線',
  `retry_time` int(11) NOT NULL COMMENT '重試次數',
  `publish_time_out` int(11) NOT NULL COMMENT '發佈超時時間',
  `publish_reasons` varchar(1023) NOT NULL COMMENT '發佈原因',
  `creator_name` varchar(255) NOT NULL COMMENT '創建者名字',
  `create_at` datetime DEFAULT NULL COMMENT '創建時間',
  `update_at` datetime DEFAULT NULL COMMENT '更新時間',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8mb4;
h2-data.sql

插入基本數據,用來做測試的數據

insert into `cmdb_docker`.`tb_publish_list` ( `name`, `project_name`, `environment`, `status`, `image`, `type`, `titan_id`, `git_commit_id`, `superior`, `is_health_check`, `is_gated_launch`, `is_traffic_publish`, `ignore_direct_connection`, `flow_check_time_out`, `hcheck_online_interval`, `publish_interval`, `publish_instance`, `old_version`, `new_version`, `offline_or_not`, `online_or_not`, `retry_time`, `publish_time_out`, `publish_reasons`, `creator_name`, `create_at`, `update_at`) values ( 'titan-publish', 'api-manager-backend-h2', 'uat', 'publish_success', 'harbor.uat.ximalaya.com/uat/api-manager-backend:20200414-051829', 'standard', '29497', 'd2844a646806e737bb2317e3451f454ed64b9a5d', 'manual', '1', '1', '0', '1', '100', '0', '0', '1', 'api-manager-backend-20200414-86', 'api-manager-backend-20200414-87', '1', '1', '5', '300', '1.qwe;\n', 'lulce.song', '2020-04-14 17:19:25', '2020-04-14 17:27:07');
insert into `cmdb_docker`.`tb_publish_list` ( `name`, `project_name`, `environment`, `status`, `image`, `type`, `titan_id`, `git_commit_id`, `superior`, `is_health_check`, `is_gated_launch`, `is_traffic_publish`, `ignore_direct_connection`, `flow_check_time_out`, `hcheck_online_interval`, `publish_interval`, `publish_instance`, `old_version`, `new_version`, `offline_or_not`, `online_or_not`, `retry_time`, `publish_time_out`, `publish_reasons`, `creator_name`, `create_at`, `update_at`) values ( 'titan-publish', 'api-manager-backend-h2', 'uat', 'publish_success', 'harbor.uat.ximalaya.com/uat/api-manager-backend:20200414-052801', 'standard', '29498', 'd2844a646806e737bb2317e3451f454ed64b9a5d', 'manual', '1', '1', '0', '1', '100', '0', '0', '1', 'api-manager-backend-20200414-87', 'api-manager-backend-20200414-88', '1', '1', '5', '300', '1.qwe;\n', 'lulce.song', '2020-04-14 17:29:32', '2020-04-14 18:28:12');

第三步,創建內嵌的h2數據庫

並且設置好DDL和DML的腳本文件


    <!--當然是配置datasource了-->
    <jdbc:embedded-database id="dataSource" type="H2">
        <!--一定要是先DDL,即數據庫定義語言-->
        <jdbc:script location="classpath:h2/h2-schema.sql"/>
        <!--然後纔是DML,數據庫操作語言-->
        <jdbc:script location="classpath:h2/h2-data.sql" encoding="UTF-8"/>
    </jdbc:embedded-database>

第四步,修改業務的datasource指向這個embedded-database.

    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:sqlmap-config.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>



    <!--當然是配置datasource了-->
    <jdbc:embedded-database id="dataSource" type="H2">
        <!--一定要是先DDL,即數據庫定義語言-->
        <jdbc:script location="classpath:h2/h2-schema.sql"/>
        <!--然後纔是DML,數據庫操作語言-->
        <jdbc:script location="classpath:h2/h2-data.sql" encoding="UTF-8"/>
    </jdbc:embedded-database>

第五步,正常開始執行單元測試就可以了。

寫在最後

有什麼看不懂的問題可以留言,我在看到評論後會做相應的解釋和回答。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章