FunTester JSON 对象标记标记语法验证工具类

FunTester · 2020年12月25日 · 748 次阅读

在接触过JsonPath工具,我发现了使用标记语法编写文本形式的验证的可行性。在完成了基本JsonPath功能封装和Groovy终极重载操作符功能之后,自我感觉已经非常完善了,所以停了一阵子。之前的成果如下:

JsonPath 文章合集

在最近实践的一个Socket接口异步验证的功能时,对于响应结果又有了新的验证需求。目前我的方案是单独写一个VerifyBean对象,用来完成不同验证需求的实现。每一个对象都是存储一种验证方式,然后存储验证结果。

对实际值进行运算

这个功能为了方便获取到实际值以后,进行运算以后再与期望值进行比较。比如用户消费场景,例如随机立减(吐槽一下立减一分钱),用余额 + 商品金额>原余额方程可以验证数据的准确性。

JsonVerify功能具体实现如下:


/**
 * 判断是否符合期望
 * @param str
 * @return
 */
public boolean fit(String str) {
    logger.info("verify对象: {},匹配的字符串: {}", extra, str)
    OPS o = OPS.getInstance(str.charAt(0))
    def res = str.substring(1)
    switch (o) {
        case OPS.GREATER:
            return this > res
        case OPS.LESS:
            return this < res
        case OPS.EQUAL:
            return this == res
        case OPS.REGEX:
            return this ==~ res
        default:
            ParamException.fail("参数错误!")
    }
}

/**
 * 判断是否符合操作后期望
 * @param str
 * @return
 */
public boolean fitFun(String str) {
    def split = str.split(REG_PART, 2)
    def handle = split[0]
    def ops = split[1]
    HPS h = HPS.getInstance(handle.charAt(0))
    def hr = handle.substring(1)
    switch (h) {
        case HPS.PLUS:
            def n = getInstance((this + hr) as String)
            return n.fit(ops)
        case HPS.MINUS:
            def n = getInstance((this - hr) as String)
            return n.fit(ops)
        case HPS.MUL:
            def n = getInstance((this * hr) as String)
            return n.fit(ops)
        case HPS.DIV:
            def n = getInstance((this / hr) as String)
            return n.fit(ops)
        default:
            ParamException.fail("参数错误!")
    }

}

/**
 * 支持的判断类型的操作符枚举类
 */
static enum OPS {

    GREATER, LESS, EQUAL, REGEX;

    static OPS getInstance(char c) {
        switch (c) {
            case '>':
                return GREATER;
            case '<':
                return LESS;
            case '=':
                return EQUAL;
            case '~':
                return REGEX
            default:
                ParamException.fail("判断操作符参数错误!")
        }
    }
}

/**
 * 支持的运算类型的操作符枚举类
 */
static enum HPS {

    PLUS, MINUS, MUL, DIV

    static HPS getInstance(char c) {
        switch (c) {
            case '+':
                return PLUS
            case '-':
                return MINUS
            case '*':
                return MUL
            case '/':
                return DIV
            default:
                ParamException.fail("运算操作符参数错误!")
        }
    }
}

重载操作符的代码可以通过JsonPath 验证类既 Groovy 重载操作符实践文章查看,或者访问我的仓库:

VerifyBean 验证对象

这个比较简单,目前来讲满足需求。

package com.fun.base.bean

import com.alibaba.fastjson.JSON
import com.fun.base.exception.ParamException
import com.fun.config.VerifyType
import com.fun.utils.JsonUtil
import com.fun.utils.Regex
import com.fun.utils.Time
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import java.util.concurrent.atomic.AtomicLong

import static com.fun.config.Constant.REG_PART

/**
 * 验证对象类
 */
class VerifyBean extends AbstractBean implements Serializable, Cloneable {

    private static Logger logger = LoggerFactory.getLogger(VerifyBean.class)

    private static final long serialVersionUID = -1595942567071153982L;

    VerifyType type

    /**
     * 验证语法
     */
    String verify
    /**
     * 待验证内容
     */
    String value

    String des

    boolean isVerify

    boolean result;

    VerifyBean(String verify, String value, String des) {
        this.value = value
        this.des = des
        def split = verify.split(REG_PART, 2)
        this.verify = split[1]
        this.type = VerifyType.getRequestType(split[0])
    }

    boolean verify() {
        isVerify = true
        try {
            switch (type) {
                case VerifyType.CONTAIN:
                    result = value.contains(verify)
                    break
                case VerifyType.REGEX:
                    result = Regex.isRegex(value, verify)
                    break
                case VerifyType.JSONPATH:
                    def split = verify.split(REG_PART, 2)
                    def path = split[0]
                    def v = split[1]
                    def instance = JsonUtil.getInstance(JSON.parseObject(value))
                    result = instance.getVerify(path).fit(v)
                    break
                case VerifyType.HANDLE:
                    def sp = verify.split(REG_PART, 2)
                    def path = sp[0]
                    def ve = sp[1]
                    def instance = JsonUtil.getInstance(JSON.parseObject(value))
                    result = instance.getVerify(path).fitFun(ve)
                    break
                default:
                    ParamException.fail("验证类型参数错误!")
            }
        } catch (Exception e) {
            logger.warn("验证出现问题!", e)
            result = false
        } finally {
            logger.info("verify对象 {} ,验证结果: {}", verify, result)
            result
        }
    }

    @Override
    public VerifyBean clone() throws CloneNotSupportedException {
        new VerifyBean(this.verify, this.value, this.des)
    }
}

Demo 演示

测试代码:

public static void main(String[] args) {
    String a = "{\"msg\":\"\",\"code\":1,\"data\":{\"role\":\"T\",\"s_sid\":123,\"deviceVersion\":\"1.0\",\"userId\":61951375269,\"token\":\"c5d28b3e919d45e0a06af2e4d346698a\"},\"cmd\":\"registerResponse\"}"
    def bean1 = new VerifyBean("contain|61951375269", a, "FunTester")
    def bean2 = new VerifyBean("regex|.*data.*", a, "FunTester")
    def bean3 = new VerifyBean("jsonpath|\$.data.s_sid|=123", a, "FunTester")
    def bean4 = new VerifyBean("jsonpath|\$.data.s_sid|>100", a, "FunTester")
    def bean5 = new VerifyBean("jsonpath|\$.cmd|~.*Response.*", a, "FunTester")
    def bean6 = new VerifyBean("handle|\$.code|*200|=200.0", a, "FunTester")
    println bean1.verify()
    println bean2.verify()
    println bean3.verify()
    println bean4.verify()
    println bean5.verify()
    println bean6.verify()

}

控制台输出:

INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> 验证校验方式方式:contain
INFO-> 验证校验方式方式:regex
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:handle
INFO-> verify对象 61951375269 ,验证结果: true
true
INFO-> verify对象 .*data.* ,验证结果: true
true
INFO-> verify对象: 123,匹配的字符串: =123
INFO-> verify对象 $.data.s_sid|=123 ,验证结果: true
true
INFO-> verify对象: 123,匹配的字符串: >100
INFO-> verify对象 $.data.s_sid|>100 ,验证结果: true
true
INFO-> verify对象: registerResponse,匹配的字符串: ~.*Response.*
INFO-> verify对象 $.cmd|~.*Response.* ,验证结果: true
true
INFO-> verify对象: 200.0,匹配的字符串: =200.0
INFO-> verify对象 $.code|*200|=200.0 ,验证结果: true
true

Process finished with exit code 0


  • FunTester,简直完美实现了我的需求,下一步开始对Socket接口编写异步验证线程,敬请期待!

FunTester,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。

FunTester 热文精选

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册