Springboot Mybatis-Plus數據庫單元測試實戰(三種方式)
單元測試長久以來是熱門話題,本文不會討論需不需要寫單測,可以看看參考資料1,我個人認為寫好單測應該是每個優秀開發者必備的技能,關於寫單測的好處在這裡我就不展開討論瞭,快速進入本文著重討論的話題,如何寫好數據庫單測。
為什麼要寫數據庫單測? 相信大傢是不是有這樣類似的經歷,在寫完復雜的sql語句後,自信滿滿的提測,發現很大一部分Bug都是因為sql語句出現問題瞭,要麼少寫逗號,要麼漏瞭字段,悔不當初哇,為啥寫完不多測測呢!
沒關系!這就教你如何寫數據庫單測,讓你輕松告別數據庫相關bug。
1. 數據庫樣例和環境
我們以用戶表為例開啟本次教程:
圖1.1 用戶表ER圖
引入mybatis-plus插件後,mapper類如下:
@Mapper public interface UserMapper extends BaseMapper<UserDO> { }
整體環境:
- spring boot: 1.5.18.RELEASE
- mybatis: 3.5.1
- mybatis plus:3.4.0(此時最新版本,我們會用到最新版本的特性)
在這裡我們直接測試的是mybatis plus提供的一些CRUD,當然這些CRUD一般都不會錯,實際項目中我們隻需對自定義的SQL進行單元測試即可。
2. 方式一:啟動整個環境
這種方式應該是日常環境使用最多的,利用SpringBoot自1.4.0版本開始引入的@SpringBootTest註解可以啟動我們單元測試所需要的所有環境,當然,如果你項目中運用瞭其他分佈式服務,他同樣也會啟動這些服務。單測代碼如下:
@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testCurd() { UserDO userDO = new UserDO(); userDO.setId(7777L); userDO.setGmtModified(new Date()); userDO.setGmtCreate(new Date()); userDO.setRealName("ke"); userDO.setUserName("ni"); userMapper.insert(userDO); UserDO select = userMapper.selectById(1); System.out.println(select); } }
@SpringBootTest註解可以設置需要啟動加載的類,按需加載
3. 方式二:隻啟動數據庫環境+遠程數據庫
在參考資料2中,最新的mybatis-plus發佈版本(3.4.0)中引入瞭test starter,如圖:
圖3.1 Mybatis-plus3.4.0引入test模塊
模塊引入瞭新的註解@MybatisPlusTest
,這個註解可以幫助我們隻啟動特定特定的模塊,直接上單測代碼:
@RunWith(SpringRunner.class) @MybatisPlusTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testCurd() { UserDO userDO = new UserDO(); userDO.setId(7777L); userDO.setGmtModified(new Date()); userDO.setGmtCreate(new Date()); userDO.setRealName("ke"); userDO.setUserName("ni"); userMapper.insert(userDO); UserDO select = userMapper.selectById(1); System.out.println(select); } }
是不是很輕松?不過我們要註意如下幾點關鍵點:
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
的作用是使用自定義的數據源,而非使用自動配置的嵌入式內存數據源- 如果你在項目正在使用類似於druid的連接池,在test模塊的時候需要在application配置文件裡面直接使用jdbc數據源即可,因為
@MybatisPlusTest
註解不會啟動連接池框架,典型的配置文件application.yml如下:
spring: datasource: url: jdbc:mysql://xxx.xxx.1.110:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8 username: root password: 123456
4. 方式三:隻啟動數據庫環境+本地數據庫
在方式二的基礎上,進行如下步驟:
- 我們去掉
@AutoConfigureTestDatabas
註解,直接啟動測試嵌入式數據庫即可,在這裡我們選用H2內存數據庫,首先在pom中引入H2 database maven依賴; - 然後後在test環境下引入sechema.sql文件,這個文件是用來初始化數據庫的,核心是創建表格語句;
- 最後去掉這個頁面以後寫法和方式二一樣,在這裡就不給出
註意: sechema.sql文件要符合嵌入式數據庫的語法,在本例中為h2數據庫,如果你正在使用mysql數據庫,則需要把mysql的數據庫語法轉換為h2的數據庫語法。
5. @MybatisPlusTest註解原理
如果你之前使用過MyBatis-Spring-Boot-Starter-Test中的@MybatisTest
(參考資料3)的話,你會發現@MybatisPlusTest
註解原理與之類似,都是限制spring boot的自動配置(參考資料4),隻需要加載特定的配置即可。我們來看一下註解源碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @BootstrapWith(MybatisPlusTestContextBootstrapper.class) @ExtendWith({SpringExtension.class}) @OverrideAutoConfiguration( enabled = false ) @TypeExcludeFilters({MybatisPlusTypeExcludeFilter.class}) @Transactional @AutoConfigureCache @AutoConfigureMybatisPlus @AutoConfigureTestDatabase @ImportAutoConfiguration public @interface MybatisPlusTest { String[] properties() default {}; boolean useDefaultFilters() default true; Filter[] includeFilters() default {}; Filter[] excludeFilters() default {}; @AliasFor( annotation = ImportAutoConfiguration.class, attribute = "exclude" ) Class<?>[] excludeAutoConfiguration() default {}; }
@OverrideAutoConfiguration(enabled = false)
是關鍵,它關閉瞭自動配置,而一般在spring boot項目中enable是開啟的;
@AutoConfigureMybatisPlus
註解是自定義註解,這個註解定義瞭加載所有所需的加載類,在spring.factories裡面聲明瞭要自動配置的類:
# AutoConfigureMybatis auto-configuration imports com.baomidou.mybatisplus.test.autoconfigure.AutoConfigureMybatisPlus=\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\ com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\ com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
@AutoConfigureTestDatabase
註解表明使用的是內存數據庫而不是真實數據庫
有瞭這些限制和規定以後,mybatis-plus在測試環境內就可以自動加載所需要的的配置瞭,這樣就去除瞭非必要資源的加載。
6. 總結
圖6.1 三種數據庫單測總結
如果你正在使用mysql數據庫,我推薦使用方式二。如果你能解決mysq語法轉h2的問題,推薦使用方式三,這樣在離線的情況也可以進行單測,不需要連接遠程數據庫。
PS:如果你有好的工具來完成mysql轉換h2的話可以在評論區裡面推薦一下,我這邊找瞭好久,包括自定義寫轉換、一些專業工具等,感覺對navicat導出的語句作轉換不是很好好用。
7.參考資料
[1] 你真的需要單元測試嗎?
[2] Mybatis-Plus發佈版本
[3] MyBatis-Spring-Boot-Starter-Test
[4] SpringBoot四大神器之auto-configuration
到此這篇關於Springboot Mybatis-Plus數據庫單元測試實戰(三種方式)的文章就介紹到這瞭,更多相關Springboot Mybatis-Plus單元測試內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 一篇超詳細的Spring Boot整合Mybatis文章
- springboot多模塊化整合mybatis,mapper自動註入失敗問題及解決
- 使用IDEA配置Mybatis-Plus框架圖文詳解
- 數據庫CURD必備搭檔mybatis plus詳解
- 基於SpringBoot整合SSMP的詳細教程