From 50a80ab86df2038d9bf2ccd233f4b88887b791bd Mon Sep 17 00:00:00 2001 From: zengxiaobo Date: Fri, 19 Apr 2024 10:42:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E5=8C=85=E5=90=8D=20?= =?UTF-8?q?&=20=E5=A2=9E=E5=8A=A0=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/foundation/exception/Axssert.java | 1 + .../exception/BusinessException.java | 1 + .../cn/axzo/foundation/result/ApiResult.java | 50 ++++ .../{exception => result}/IResultCode.java | 3 +- .../cn/axzo/foundation/result/ResultCode.java | 1 - .../{data => }/converter/PageConverter.java | 8 +- .../{data => }/mysql/JsonImportHelper.java | 4 +- .../mysql/MybatisPlusCacheHelper.java | 2 +- .../mysql/MybatisPlusConverterUtils.java | 6 +- .../{data => }/mysql/MybatisPlusHelper.java | 2 +- .../mysql/MybatisPlusOperatorProcessor.java | 10 +- .../{data => }/mysql/MysqlJsonHelper.java | 2 +- .../{data => }/mysql/QueryWrapperHelper.java | 6 +- .../mysql/plugins/LimitInterceptor.java | 2 +- .../mysql/plugins/SlowQueryInterceptor.java | 2 +- .../mysql/type/BaseListTypeHandler.java | 2 +- .../mysql/type/BaseSetTypeHandler.java | 2 +- .../mysql/type/LinkedHashSetTypeHandler.java | 2 +- .../{data => }/mysql/type/SetTypeHandler.java | 2 +- .../dao/support/{data => }/page/IPageReq.java | 2 +- .../dao/support/{data => }/page/PageResp.java | 2 +- .../dao/support/{data => }/utils/BitMask.java | 2 +- .../{data => }/utils/RepairDataHelper.java | 6 +- .../{data => }/wrapper/CriteriaField.java | 3 +- .../{data => }/wrapper/CriteriaWrapper.java | 2 +- .../support/{data => }/wrapper/Operator.java | 2 +- .../{data => }/wrapper/OperatorProcessor.java | 2 +- .../wrapper/SimpleWrapperConverter.java | 2 +- .../{data => }/wrapper/TriConsumer.java | 2 +- pom.xml | 1 + unittest-support-lib/pom.xml | 90 ++++++ .../foundation/unittest/support/BaseTest.java | 130 +++++++++ .../unittest/support/config/MysqlConfig.java | 20 ++ .../support/config/MysqlDataLoader.java | 132 +++++++++ .../unittest/support/config/RedisConfig.java | 31 ++ .../unittest/support/config/TestConfig.java | 17 ++ .../support/config/TransactionalConfig.java | 45 +++ .../unittest/support/h2/JsonFunctions.java | 271 ++++++++++++++++++ .../unittest/support/h2/StringFunctions.java | 23 ++ 39 files changed, 852 insertions(+), 41 deletions(-) create mode 100644 common-lib/src/main/java/cn/axzo/foundation/result/ApiResult.java rename common-lib/src/main/java/cn/axzo/foundation/{exception => result}/IResultCode.java (94%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/converter/PageConverter.java (93%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/JsonImportHelper.java (99%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/MybatisPlusCacheHelper.java (98%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/MybatisPlusConverterUtils.java (95%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/MybatisPlusHelper.java (99%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/MybatisPlusOperatorProcessor.java (97%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/MysqlJsonHelper.java (98%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/QueryWrapperHelper.java (94%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/plugins/LimitInterceptor.java (98%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/plugins/SlowQueryInterceptor.java (98%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/type/BaseListTypeHandler.java (97%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/type/BaseSetTypeHandler.java (97%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/type/LinkedHashSetTypeHandler.java (97%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/mysql/type/SetTypeHandler.java (97%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/page/IPageReq.java (92%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/page/PageResp.java (91%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/utils/BitMask.java (99%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/utils/RepairDataHelper.java (98%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/CriteriaField.java (95%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/CriteriaWrapper.java (99%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/Operator.java (96%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/OperatorProcessor.java (88%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/SimpleWrapperConverter.java (99%) rename dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/{data => }/wrapper/TriConsumer.java (81%) create mode 100644 unittest-support-lib/pom.xml create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/BaseTest.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlConfig.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlDataLoader.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/RedisConfig.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TestConfig.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TransactionalConfig.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/JsonFunctions.java create mode 100644 unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/StringFunctions.java diff --git a/common-lib/src/main/java/cn/axzo/foundation/exception/Axssert.java b/common-lib/src/main/java/cn/axzo/foundation/exception/Axssert.java index b597c3e..bba5f49 100644 --- a/common-lib/src/main/java/cn/axzo/foundation/exception/Axssert.java +++ b/common-lib/src/main/java/cn/axzo/foundation/exception/Axssert.java @@ -1,5 +1,6 @@ package cn.axzo.foundation.exception; +import cn.axzo.foundation.result.IResultCode; import com.google.common.base.Strings; import java.util.Collection; diff --git a/common-lib/src/main/java/cn/axzo/foundation/exception/BusinessException.java b/common-lib/src/main/java/cn/axzo/foundation/exception/BusinessException.java index fbe224f..3d817cb 100644 --- a/common-lib/src/main/java/cn/axzo/foundation/exception/BusinessException.java +++ b/common-lib/src/main/java/cn/axzo/foundation/exception/BusinessException.java @@ -1,6 +1,7 @@ package cn.axzo.foundation.exception; +import cn.axzo.foundation.result.IResultCode; import lombok.Getter; /** diff --git a/common-lib/src/main/java/cn/axzo/foundation/result/ApiResult.java b/common-lib/src/main/java/cn/axzo/foundation/result/ApiResult.java new file mode 100644 index 0000000..b52b985 --- /dev/null +++ b/common-lib/src/main/java/cn/axzo/foundation/result/ApiResult.java @@ -0,0 +1,50 @@ +package cn.axzo.foundation.result; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ApiResult { + private static final String SUCCESS_HTTP_CODE = "200"; + private static final String FAILED_HTTP_CODE = "400"; + + private String code; + + private String msg; + + private T data; + + public static ApiResult success() { + return success(null); + } + + public static ApiResult success(T data) { + return ApiResult.builder() + .code(SUCCESS_HTTP_CODE) + .data(data) + .build(); + } + + public static ApiResult error(String msg) { + return ApiResult.builder() + .code(FAILED_HTTP_CODE) + .msg(msg) + .build(); + } + + public static ApiResult error(IResultCode resultCode) { + return error(resultCode.getErrorCode(), resultCode.getErrorMessage()); + } + + public static ApiResult error(String code, String msg) { + return ApiResult.builder() + .code(code) + .msg(msg) + .build(); + } +} diff --git a/common-lib/src/main/java/cn/axzo/foundation/exception/IResultCode.java b/common-lib/src/main/java/cn/axzo/foundation/result/IResultCode.java similarity index 94% rename from common-lib/src/main/java/cn/axzo/foundation/exception/IResultCode.java rename to common-lib/src/main/java/cn/axzo/foundation/result/IResultCode.java index 370cf3f..0cb4bbb 100644 --- a/common-lib/src/main/java/cn/axzo/foundation/exception/IResultCode.java +++ b/common-lib/src/main/java/cn/axzo/foundation/result/IResultCode.java @@ -1,5 +1,6 @@ -package cn.axzo.foundation.exception; +package cn.axzo.foundation.result; +import cn.axzo.foundation.exception.BusinessException; import cn.axzo.foundation.util.VarParamFormatter; public interface IResultCode { diff --git a/common-lib/src/main/java/cn/axzo/foundation/result/ResultCode.java b/common-lib/src/main/java/cn/axzo/foundation/result/ResultCode.java index 8906522..2f26071 100644 --- a/common-lib/src/main/java/cn/axzo/foundation/result/ResultCode.java +++ b/common-lib/src/main/java/cn/axzo/foundation/result/ResultCode.java @@ -1,6 +1,5 @@ package cn.axzo.foundation.result; -import cn.axzo.foundation.exception.IResultCode; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/converter/PageConverter.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/converter/PageConverter.java similarity index 93% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/converter/PageConverter.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/converter/PageConverter.java index 2838031..cccd83b 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/converter/PageConverter.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/converter/PageConverter.java @@ -1,8 +1,8 @@ -package cn.axzo.foundation.dao.support.data.converter; +package cn.axzo.foundation.dao.support.converter; -import cn.axzo.foundation.dao.support.data.mysql.MybatisPlusConverterUtils; -import cn.axzo.foundation.dao.support.data.page.IPageReq; -import cn.axzo.foundation.dao.support.data.page.PageResp; +import cn.axzo.foundation.dao.support.mysql.MybatisPlusConverterUtils; +import cn.axzo.foundation.dao.support.page.IPageReq; +import cn.axzo.foundation.dao.support.page.PageResp; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.google.common.collect.Lists; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/JsonImportHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/JsonImportHelper.java similarity index 99% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/JsonImportHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/JsonImportHelper.java index b2a0423..b841b58 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/JsonImportHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/JsonImportHelper.java @@ -1,6 +1,6 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; -import cn.axzo.foundation.dao.support.data.mysql.type.SetTypeHandler; +import cn.axzo.foundation.dao.support.mysql.type.SetTypeHandler; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusCacheHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusCacheHelper.java similarity index 98% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusCacheHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusCacheHelper.java index 248bf10..c232ed5 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusCacheHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusCacheHelper.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusConverterUtils.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusConverterUtils.java similarity index 95% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusConverterUtils.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusConverterUtils.java index 30169c7..856916f 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusConverterUtils.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusConverterUtils.java @@ -1,7 +1,7 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; -import cn.axzo.foundation.dao.support.data.page.IPageReq; -import cn.axzo.foundation.dao.support.data.wrapper.SimpleWrapperConverter; +import cn.axzo.foundation.dao.support.page.IPageReq; +import cn.axzo.foundation.dao.support.wrapper.SimpleWrapperConverter; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusHelper.java similarity index 99% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusHelper.java index 7e1cc49..b475c2d 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusHelper.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; import cn.axzo.foundation.exception.Axssert; import cn.axzo.foundation.result.ResultCode; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusOperatorProcessor.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusOperatorProcessor.java similarity index 97% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusOperatorProcessor.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusOperatorProcessor.java index ff0ca5d..0308f2e 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MybatisPlusOperatorProcessor.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MybatisPlusOperatorProcessor.java @@ -1,9 +1,9 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; -import cn.axzo.foundation.dao.support.data.wrapper.CriteriaWrapper; -import cn.axzo.foundation.dao.support.data.wrapper.Operator; -import cn.axzo.foundation.dao.support.data.wrapper.OperatorProcessor; -import cn.axzo.foundation.dao.support.data.wrapper.TriConsumer; +import cn.axzo.foundation.dao.support.wrapper.CriteriaWrapper; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.dao.support.wrapper.OperatorProcessor; +import cn.axzo.foundation.dao.support.wrapper.TriConsumer; import cn.axzo.foundation.exception.Axssert; import cn.axzo.foundation.exception.BusinessException; import cn.axzo.foundation.result.ResultCode; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MysqlJsonHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MysqlJsonHelper.java similarity index 98% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MysqlJsonHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MysqlJsonHelper.java index bf9bb26..d7ebf2f 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/MysqlJsonHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/MysqlJsonHelper.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/QueryWrapperHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/QueryWrapperHelper.java similarity index 94% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/QueryWrapperHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/QueryWrapperHelper.java index e90fed6..524ce00 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/QueryWrapperHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/QueryWrapperHelper.java @@ -1,7 +1,7 @@ -package cn.axzo.foundation.dao.support.data.mysql; +package cn.axzo.foundation.dao.support.mysql; -import cn.axzo.foundation.dao.support.data.wrapper.CriteriaWrapper; -import cn.axzo.foundation.dao.support.data.wrapper.SimpleWrapperConverter; +import cn.axzo.foundation.dao.support.wrapper.CriteriaWrapper; +import cn.axzo.foundation.dao.support.wrapper.SimpleWrapperConverter; import cn.axzo.foundation.exception.Axssert; import cn.axzo.foundation.result.ResultCode; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/LimitInterceptor.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/LimitInterceptor.java similarity index 98% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/LimitInterceptor.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/LimitInterceptor.java index cc26ab4..1839f00 100755 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/LimitInterceptor.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/LimitInterceptor.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.plugins; +package cn.axzo.foundation.dao.support.mysql.plugins; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import com.google.common.base.Strings; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/SlowQueryInterceptor.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/SlowQueryInterceptor.java similarity index 98% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/SlowQueryInterceptor.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/SlowQueryInterceptor.java index e642e92..9f56874 100755 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/plugins/SlowQueryInterceptor.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/plugins/SlowQueryInterceptor.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.plugins; +package cn.axzo.foundation.dao.support.mysql.plugins; import com.alibaba.fastjson.annotation.JSONField; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseListTypeHandler.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseListTypeHandler.java similarity index 97% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseListTypeHandler.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseListTypeHandler.java index 8228d53..a8bb150 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseListTypeHandler.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseListTypeHandler.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.type; +package cn.axzo.foundation.dao.support.mysql.type; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.serializer.SerializerFeature; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseSetTypeHandler.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseSetTypeHandler.java similarity index 97% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseSetTypeHandler.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseSetTypeHandler.java index 0409ae6..4095187 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/BaseSetTypeHandler.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/BaseSetTypeHandler.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.type; +package cn.axzo.foundation.dao.support.mysql.type; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.serializer.SerializerFeature; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/LinkedHashSetTypeHandler.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/LinkedHashSetTypeHandler.java similarity index 97% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/LinkedHashSetTypeHandler.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/LinkedHashSetTypeHandler.java index f9234dc..28b41fc 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/LinkedHashSetTypeHandler.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/LinkedHashSetTypeHandler.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.type; +package cn.axzo.foundation.dao.support.mysql.type; import com.google.common.base.Joiner; import com.google.common.base.Splitter; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/SetTypeHandler.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/SetTypeHandler.java similarity index 97% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/SetTypeHandler.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/SetTypeHandler.java index 4abfc94..bdad8bf 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/mysql/type/SetTypeHandler.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/mysql/type/SetTypeHandler.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.mysql.type; +package cn.axzo.foundation.dao.support.mysql.type; import com.google.common.base.Splitter; import com.google.common.collect.Sets; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/IPageReq.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/IPageReq.java similarity index 92% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/IPageReq.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/IPageReq.java index 5d5e6d1..fc0d8f9 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/IPageReq.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/IPageReq.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.page; +package cn.axzo.foundation.dao.support.page; import cn.axzo.foundation.enums.OrderEnum; import com.google.common.collect.ImmutableList; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/PageResp.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/PageResp.java similarity index 91% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/PageResp.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/PageResp.java index 9054fe4..870f7bd 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/page/PageResp.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/page/PageResp.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.page; +package cn.axzo.foundation.dao.support.page; import com.google.common.collect.ImmutableList; import lombok.AllArgsConstructor; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/BitMask.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/BitMask.java similarity index 99% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/BitMask.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/BitMask.java index 348de55..4f02c20 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/BitMask.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/BitMask.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.utils; +package cn.axzo.foundation.dao.support.utils; import cn.axzo.foundation.enums.AppEnvEnum; import com.google.common.collect.ImmutableList; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/RepairDataHelper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/RepairDataHelper.java similarity index 98% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/RepairDataHelper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/RepairDataHelper.java index 66de627..00e7abb 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/utils/RepairDataHelper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/utils/RepairDataHelper.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.utils; +package cn.axzo.foundation.dao.support.utils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; @@ -6,8 +6,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import cn.axzo.foundation.dao.support.data.mysql.MybatisPlusConverterUtils; -import cn.axzo.foundation.dao.support.data.wrapper.SimpleWrapperConverter; +import cn.axzo.foundation.dao.support.mysql.MybatisPlusConverterUtils; +import cn.axzo.foundation.dao.support.wrapper.SimpleWrapperConverter; import com.google.common.base.Preconditions; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaField.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaField.java similarity index 95% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaField.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaField.java index d12e55b..4e58f08 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaField.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaField.java @@ -1,10 +1,9 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.function.Function; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaWrapper.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaWrapper.java similarity index 99% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaWrapper.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaWrapper.java index a31bd4e..f16b774 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/CriteriaWrapper.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/CriteriaWrapper.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; import com.google.common.base.Preconditions; import com.google.common.base.Strings; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/Operator.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/Operator.java similarity index 96% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/Operator.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/Operator.java index 35ca66e..ea54c25 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/Operator.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/Operator.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/OperatorProcessor.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/OperatorProcessor.java similarity index 88% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/OperatorProcessor.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/OperatorProcessor.java index c82fd53..af87762 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/OperatorProcessor.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/OperatorProcessor.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; import com.google.common.collect.ImmutableListMultimap; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/SimpleWrapperConverter.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/SimpleWrapperConverter.java similarity index 99% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/SimpleWrapperConverter.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/SimpleWrapperConverter.java index 498e7c2..8fda6d3 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/SimpleWrapperConverter.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/SimpleWrapperConverter.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; import cn.axzo.foundation.exception.BusinessException; import cn.axzo.foundation.result.ResultCode; diff --git a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/TriConsumer.java b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/TriConsumer.java similarity index 81% rename from dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/TriConsumer.java rename to dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/TriConsumer.java index 84b4ed1..01b527f 100644 --- a/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/data/wrapper/TriConsumer.java +++ b/dao-support-lib/src/main/java/cn/axzo/foundation/dao/support/wrapper/TriConsumer.java @@ -1,4 +1,4 @@ -package cn.axzo.foundation.dao.support.data.wrapper; +package cn.axzo.foundation.dao.support.wrapper; /** * 仅包内可访问 diff --git a/pom.xml b/pom.xml index d437a7e..2ab0996 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ dao-support-lib common-lib + unittest-support-lib diff --git a/unittest-support-lib/pom.xml b/unittest-support-lib/pom.xml new file mode 100644 index 0000000..ae9b50f --- /dev/null +++ b/unittest-support-lib/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + cn.axzo.foundation + axzo-lib-box + 2.0.0-SNAPSHOT + + + unittest-support-lib + + + + cn.axzo.foundation + common-lib + 2.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + mysql + mysql-connector-java + provided + + + com.baomidou + mybatis-plus-boot-starter + provided + + + org.springframework.boot + spring-boot-starter-data-redis + provided + + + + com.alibaba + fastjson + + + org.apache.commons + commons-lang3 + + + + + org.springframework.boot + spring-boot-starter-test + + + junit + junit + + + org.junit.vintage + junit-vintage-engine + + + compile + + + org.junit.jupiter + junit-jupiter-engine + compile + + + org.junit.jupiter + junit-jupiter-api + compile + + + com.h2database + h2 + compile + + + it.ozimov + embedded-redis + 0.7.3 + compile + + + + \ No newline at end of file diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/BaseTest.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/BaseTest.java new file mode 100644 index 0000000..2093ce7 --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/BaseTest.java @@ -0,0 +1,130 @@ +package cn.axzo.foundation.unittest.support; + +import cn.axzo.foundation.result.ApiResult; +import cn.axzo.foundation.unittest.support.config.MysqlConfig; +import cn.axzo.foundation.unittest.support.config.RedisConfig; +import cn.axzo.foundation.unittest.support.config.TestConfig; +import cn.axzo.foundation.unittest.support.config.TransactionalConfig; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import com.google.common.io.Files; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.util.AopTestUtils; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.Assert; +import org.springframework.util.ResourceUtils; +import org.springframework.web.context.WebApplicationContext; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +@Import(value = {TestConfig.class, MysqlConfig.class, RedisConfig.class, TransactionalConfig.class}) +@ContextConfiguration +@ExtendWith(SpringExtension.class) +@SpringBootTest +@AutoConfigureMockMvc +@Transactional +@ActiveProfiles("unittest") +@ComponentScan("cn.axzo.**.config") +@RequiredArgsConstructor +public abstract class BaseTest { + private static final String JSON_FILE_CLASSPATH = "classpath:json/"; + /** + * 记录对象原始的 field 值. 因为这些值可能被mock替换, 在每次执行单元测试前统一进行一次替换恢复 + * 避免影响后续的单元测试. + */ + private static Table ORIGIN_FIELD_TABLE = HashBasedTable.create(); + + protected final MockMvc mockMvc; + + protected final WebApplicationContext context; + + @BeforeEach + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void teardown() { + // restore origin value of field. + ORIGIN_FIELD_TABLE.cellSet().stream().forEach(e -> { + ReflectionTestUtils.setField(e.getRowKey(), e.getColumnKey(), e.getValue()); + }); + } + + protected T unwrapProxy(Object bean) { + return AopTestUtils.getUltimateTargetObject(bean); + } + + /** + * 设置对象field为mock对象. teardown时恢复成原spring代理的对象 + */ + protected void setMockField(Object targetObject, String fieldName, Object value) { + // 保存一份默认值 + Object oldField = ReflectionTestUtils.getField(targetObject, fieldName); + ReflectionTestUtils.setField(targetObject, fieldName, value); + + if (!ORIGIN_FIELD_TABLE.contains(targetObject, fieldName) && oldField != null) { + ORIGIN_FIELD_TABLE.put(targetObject, fieldName, oldField); + } + } + + protected MockHttpServletRequestBuilder buildJsonRequest(String path, Object object) { + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders + .post(path) + .contentType(MediaType.APPLICATION_JSON) + .content(JSONObject.toJSONString(object)); + return builder; + } + + protected ApiResult getResult(MvcResult result, Class clz) throws Exception { + return getResult(result, new TypeReference>(clz) { + }); + } + + protected ApiResult getResult(MvcResult result, TypeReference> typeReference) throws Exception { + Assert.notNull(result, "Result must not be null"); + String response = result.getResponse().getContentAsString(); + return JSONObject.parseObject(response, typeReference); + } + + public T loadJson(String fileName, Class clz) { + try { + String jsonString = Files.asCharSource(ResourceUtils.getFile(JSON_FILE_CLASSPATH + fileName), StandardCharsets.UTF_8).read(); + return JSON.parseObject(jsonString, clz); + } catch (IOException e) { + throw new RuntimeException("loadJson got error", e); + } + } + + public List loadJsonAsList(String fileName, Class clz) { + try { + String jsonString = Files.asCharSource(ResourceUtils.getFile(JSON_FILE_CLASSPATH + fileName), StandardCharsets.UTF_8).read(); + return JSONArray.parseArray(jsonString, clz); + } catch (IOException e) { + throw new RuntimeException("loadJsonAsList got error", e); + } + } +} diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlConfig.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlConfig.java new file mode 100644 index 0000000..49f98fc --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlConfig.java @@ -0,0 +1,20 @@ +package cn.axzo.foundation.unittest.support.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.core.JdbcTemplate; + +/** + * 如果mysql/h2存在时增加的配置 + * 1. 构造DataLoader + */ +@ConditionalOnClass({JdbcTemplate.class}) +public class MysqlConfig { + + @Bean + public MysqlDataLoader mysqlDataLoader() { + return new MysqlDataLoader(); + } + +} + diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlDataLoader.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlDataLoader.java new file mode 100644 index 0000000..dbcc11a --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/MysqlDataLoader.java @@ -0,0 +1,132 @@ +package cn.axzo.foundation.unittest.support.config; + +import com.google.common.base.Joiner; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.io.Files; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.util.ResourceUtils; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * mysql 测试数据加载 + *

+ * 测试数据后缀.sql, 默认加载 DEFAULT section 的数据. 如果需要加载指定section的数据需要带上sectionName + * + *

+ * 文件中通过 "#-->"来定义section. loader可以加载指定section的数据. + *

+ *

+ * 文件路径: test/resources/mysql/${testClassName}.sql. + *

+ * 数据格式如下 + *

+ * #-->DEFAULT
+ * sql statement1;
+ * sql statement2;
+ *
+ * #-->section1
+ * sql statement3;
+ * sql statement4;
+ *
+ * #-->section2
+ * sql statement5;
+ * 
+ * + * @author chenjun + */ +@Slf4j +public class MysqlDataLoader { + + private final static String MYSQL_DATA_PATH = "classpath:mysql/"; + private final static String MYSQL_FILE_SUFFIX = ".sql"; + private final static String DEFAULT_SECTION = "DEFAULT"; + + @Autowired + private JdbcTemplate jdbcTemplate; + + private LoadingCache> sqlFileCaches = CacheBuilder.newBuilder() + .build(new CacheLoader>() { + @SuppressWarnings("NullableProblems") + public Multimap load(File file) throws Exception { + List lines = Files.asCharSource(file, Charset.forName("utf-8")).readLines(); + String sectionFlag = "#-->"; + Multimap sections = LinkedListMultimap.create(); + String currentSectionName = ""; + // 按照section分组. + for (String line : lines) { + line = line.trim(); + if (StringUtils.isAllBlank(line)) { + continue; + } + String sectionName = StringUtils.substringAfter(line, sectionFlag); + if (org.apache.logging.log4j.util.Strings.isNotBlank(sectionName)) { + currentSectionName = sectionName; + } else { + sections.put(currentSectionName, line); + } + } + return sections; + } + }); + + public void loadFromClassName(String className) { + String locationPattern = MYSQL_DATA_PATH + className + MYSQL_FILE_SUFFIX; + File file = getFile(locationPattern); + execStatements(file, ImmutableList.of(DEFAULT_SECTION)); + } + + + public void loadFromClassName(String className, List includeSections) { + String locationPattern = MYSQL_DATA_PATH + className + MYSQL_FILE_SUFFIX; + File file = getFile(locationPattern); + execStatements(file, includeSections); + } + + public void load(String filePath) { + String locationPattern = MYSQL_DATA_PATH + filePath; + File file = getFile(locationPattern); + execStatements(file, ImmutableList.of(DEFAULT_SECTION)); + } + + public void load(String filePath, List includeSections) { + String locationPattern = MYSQL_DATA_PATH + filePath; + File file = getFile(locationPattern); + execStatements(file, includeSections); + } + + private File getFile(String locationPattern) { + File file; + try { + file = ResourceUtils.getFile(locationPattern); + } catch (Exception ex) { + throw new RuntimeException("try get file error", ex); + } + return file; + } + + private void execStatements(File file, List includeSections) { + Multimap sections = sqlFileCaches.getUnchecked(file); + List statements = sections.entries().stream() + .filter(e -> includeSections.isEmpty() || includeSections.contains(e.getKey())) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + String sql = Joiner.on("\n").join(statements); + log.info("\n>>>>>>>>>>>>>>> Execute SQL {}\n {}", Joiner.on(",").join(includeSections), sql); + jdbcTemplate.update(sql); + log.info("<<<<<<<<<<<<< Execute DONE\n"); + } + +} diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/RedisConfig.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/RedisConfig.java new file mode 100644 index 0000000..922c827 --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/RedisConfig.java @@ -0,0 +1,31 @@ +package cn.axzo.foundation.unittest.support.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.data.redis.core.RedisTemplate; +import redis.embedded.RedisServer; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +/** + * redis存在时, 处理相关配置 + * 1. 启动embedded的redis + */ +@ConditionalOnClass({RedisTemplate.class}) +public class RedisConfig { + private RedisServer redisServer; + + @PostConstruct + public void postConstruct() { + redisServer = new RedisServer(16379); + // redis server会在后台启动一个redis server的进程,默认IP=127.0.0.1 + redisServer.start(); + } + + @PreDestroy + public void preDestroy() { + // 测试结束后必须调用redisServer.stop(), 否则后台运行的redis server进程会一直存在并占用6379端口 + redisServer.stop(); + } + +} diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TestConfig.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TestConfig.java new file mode 100644 index 0000000..022c50d --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TestConfig.java @@ -0,0 +1,17 @@ +package cn.axzo.foundation.unittest.support.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.core.task.SyncTaskExecutor; +import org.springframework.core.task.TaskExecutor; + +@Slf4j +public class TestConfig { + + @Bean + @Primary + public TaskExecutor mockTaskExecutor() { + return new SyncTaskExecutor(); + } +} diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TransactionalConfig.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TransactionalConfig.java new file mode 100644 index 0000000..9490364 --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/config/TransactionalConfig.java @@ -0,0 +1,45 @@ +package cn.axzo.foundation.unittest.support.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.annotation.Bean; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionManager; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; +import org.springframework.transaction.support.DefaultTransactionStatus; + +/** + * 构造TransactionManager + * 如果没有mysql/h2时 构造一个空的TransactionManager + */ +@ConditionalOnMissingClass(value = {"org.springframework.jdbc.core.JdbcTemplate"}) +public class TransactionalConfig { + + @Bean + public TransactionManager transactionManager() { + return new AbstractPlatformTransactionManager() { + + @Override + protected Object doGetTransaction() throws TransactionException { + return new Object(); + } + + @Override + protected void doBegin(Object o, TransactionDefinition transactionDefinition) throws TransactionException { + + } + + @Override + protected void doCommit(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException { + + } + + @Override + protected void doRollback(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException { + + } + }; + } + +} + diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/JsonFunctions.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/JsonFunctions.java new file mode 100644 index 0000000..07fbae1 --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/JsonFunctions.java @@ -0,0 +1,271 @@ +package cn.axzo.foundation.unittest.support.h2; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.google.common.collect.Sets; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.util.StringUtils; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 用于支持h2兼容mysql中json的函数 + * eg: + * CREATE ALIAS `JSON_EXTRACT` FOR "com.fiture.bfs.unittest.h2.JsonFunctions.extract"; + * CREATE ALIAS `JSON_CONTAINS` FOR "com.fiture.bfs.unittest.h2.JsonFunctions.contains"; + * CREATE ALIAS `JSON_LENGTH` FOR "com.fiture.bfs.unittest.h2.JsonFunctions.length"; + * + * NOTE: JSON.parse(json, Feature.AutoCloseSource)其中Feature.AutoCloseSource是为了兼容fastjson2. 默认该feature在JSON中已经开启 + */ +public class JsonFunctions { + /** + * 分割符号 + */ + public static final String SEPARATOR = "\\."; + + /** + * 根标识符名称 + */ + public static final String ROOT_KEY_NAME = "$"; + + /** + * 数组所有行下标符号 + */ + public static final String ARRAY_ANY_INDEX = "*"; + + /** + * 正则表达式数组匹配模式 + */ + public static final Pattern ARRAY_KEY_PATTERN = Pattern.compile("\\[ *(\\*|\\d+) *\\]"); + + /** + * 根据属性标识从对象中提取数据 + * + * @param object 数据对象 + * @param key 属性标识 + * @return 值对象 + */ + private static Object extract(Object object, Key key) { + if (object == null || key == null) { + return object; + } else if (key instanceof PropertyKey) { + String name = ((PropertyKey) key).name; + Object value = + ROOT_KEY_NAME.equals(name) ? object : object instanceof Map ? ((Map) object).get(name) : null; + return extract(value, key.next); + } else if (key instanceof ArrayKey && object instanceof List) { + List list = (List) object; + Integer index = ((ArrayKey) key).index; + return index == null ? list.stream().flatMap(o -> { + Object value = extract(o, key.next); + return value instanceof Collection ? ((Collection) value).stream() : Stream.of(value); + }).filter(Objects::nonNull).collect(Collectors.toList()) + : list.size() < index + 1 ? null : extract(list.get(index), key.next); + } + return null; + } + + /** + * 根据指定属性标识从JSON数据中抽取数据 + * + * @param json JSON数据 + * @param key 属性标识 + * @return JSON数据结果 + */ + public static String extract(String json, String key) { + Object value = extract(JSON.parse(json, Feature.AutoCloseSource), Key.parse(key)); + return value == null ? null : convert2str(value); + } + + /** + * 结果值转换。 + *

解决字符串toJSON的时候被添加双引号的问题 + * + * @param value + * @return + */ + private static String convert2str(Object value) { + if (value instanceof Map || value instanceof Collection) { + return JSON.toJSONString(value); + } else { + return String.valueOf(value); + } + } + + /** + * 根据指定属性标识判断值是否在JSON数据中存在 + * + * @param json JSON数据 + * @param value 值 + * @param key 属性标识 + * @return 真假数字(true:1、false:0) + */ + public static int contains(String json, String value, String key) { + if (!StringUtils.isEmpty(json) && !StringUtils.isEmpty(value)) { + Object data = extract(JSON.parse(json, Feature.AutoCloseSource), Key.parse(key)); + Object target = JSON.parse(value, Feature.AutoCloseSource); + return targetInJsonData(data, target); + } + return 0; + } + + /** + * 根据指定属性标识判断值是否在JSON数据中存在 + * + * @param json JSON数据 + * @param value 值 + * @return 真假数字(true:1、false:0) + */ + public static int contains(String json, String value) { + if (!StringUtils.isEmpty(json) && !StringUtils.isEmpty(value)) { + Object data = JSON.parse(json, Feature.AutoCloseSource); + Object target = JSON.parse(value, Feature.AutoCloseSource); + return targetInJsonData(data, target); + } + return 0; + } + + private static int targetInJsonData(Object data, Object target) { + if (data instanceof List) { + return ((List) data).stream().filter(Objects::nonNull).collect(Collectors.toSet()) + .containsAll(target instanceof List + ? ((List) target).stream().filter(Objects::nonNull).collect(Collectors.toSet()) + : Sets.newHashSet(target)) ? 1 : 0; + } else if (target instanceof List) { + return ((List) target).contains(data) ? 1 : 0; + } + return data != null && target != null && Objects.equals(data, target) ? 1 : 0; + } + + /** + * 去除字符串双引号 + * + * @param value + * @return + */ + public static String unquote(String value) { + return StringUtils.isEmpty(value) ? value : value.replaceAll("\"", ""); + } + + /** + * 获取JSON数据长度 + * + * @param json JSON字符串 + * @return 长度 + */ + public static Integer length(String json) { + Object object = JSON.parse(json, Feature.AutoCloseSource); + return object instanceof Map ? ((Map) object).size() + : object instanceof Collection ? ((Collection) object).size() : 0; + } + + /** + * 属性标识 + */ + @Data + @SuperBuilder + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) + private static class Key { + /** + * 下一个标识 + */ + private Key next; + + /** + * 上一个标识 + */ + private Key parent; + + /** + * 获取跟标识 + * + * @return 标识 + */ + private Key getRoot() { + return this.parent == null ? this : this.parent.getRoot(); + } + + /** + * 属性标识链最后追加属性标识 + * + * @param key 追加的属性标识 + * @return 最后的属性标识 + */ + private Key append(Key key) { + Key last = this; + while (last.next != null) { + last = last.next; + } + last.setNext(key); + key.setParent(last); + return key; + } + + /** + * 属性标识转换 + * + * @param text 属性标识字符串形式 + * @return 属性标识对象 + */ + public static Key parse(String text) { + Key key = null; + if (!StringUtils.isEmpty(text == null ? null : text.trim())) { + for (String s : text.split(SEPARATOR)) { + String name = ARRAY_KEY_PATTERN.split(s = s.trim())[0]; + PropertyKey property = PropertyKey.builder().name(name.trim()).build(); + key = key == null ? property : key.append(property); + Matcher matcher = ARRAY_KEY_PATTERN.matcher(s); + while (matcher.find()) { + String group = matcher.group().trim(); + String index = group.substring(1, group.length() - 1).trim(); + key = key.append(ArrayKey.builder() + .index(ARRAY_ANY_INDEX.equals(index) ? null : Integer.parseInt(index)).build()); + } + } + } + return key.getRoot(); + } + } + + /** + * 字段属性标识 + */ + @Data + @SuperBuilder + @NoArgsConstructor + @AllArgsConstructor + private static class PropertyKey extends Key { + /** + * 属性名称 + */ + private String name; + } + + /** + * 数组属性标识 + */ + @Data + @SuperBuilder + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) + private static class ArrayKey extends Key { + /** + * 数组下标,如果为空则表示引用所有记录 + */ + private Integer index; + } +} \ No newline at end of file diff --git a/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/StringFunctions.java b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/StringFunctions.java new file mode 100644 index 0000000..925e36f --- /dev/null +++ b/unittest-support-lib/src/main/java/cn/axzo/foundation/unittest/support/h2/StringFunctions.java @@ -0,0 +1,23 @@ +package cn.axzo.foundation.unittest.support.h2; + +import java.util.Arrays; +import java.util.Objects; + +/** + * 用于支持h2兼容mysql中string的函数 + * eg: + * CREATE ALIAS FIND_IN_SET FOR "com.fiture.bfs.unittest.h2.StringFunctions.findInSet"; + */ +public class StringFunctions { + + /** + * CREATE ALIAS FIND_IN_SET FOR "com.fiture.bfs.unittest.h2.StringFunctions.findInSet"; + */ + public static Integer findInSet(String str, String strList) { + if (!Objects.isNull(str) && !Objects.isNull(strList)) { + return strList.isEmpty() ? 0 : Arrays.asList(strList.split(",")).indexOf(str) + 1; + } else { + return null; + } + } +}