Groovy动态添加方法和属性及Spock单测

摘要:
在最近的一边学习一边复习的过程中,发现了很多有意思的事情。对于Java、Groovy来讲,如果用到一个类,那么这个类的属性和方法已经是固定的,可是随着我的学习,发现这个常识并不靠谱。下面开始我的表演。

在最近的一边学习一边复习的过程中,发现了很多有意思的事情。今天就分享一个groovy.lang.MetaClass应用:如何运行中,动态给类和对象增加属性和添加方法。

对于Java、Groovy来讲,如果用到一个类,那么这个类的属性和方法已经是固定的,可是随着我的学习,发现这个常识并不靠谱。下面开始我的表演。

添加对象方法

下面是简化的语法object.metaClass.object_method = {闭包},如下:

        def funTester = new FunTester()
        funTester.metaClass.test = {
            logger.info("我是测试方法:{}","test")
        }
        funTester.test()

控制台输出:

INFO-> main 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> main 我是测试方法:test

Process finished with exit code 0
添加静态方法

下面是简化的语法object.metaClass.static.object_method = {闭包},如下:

        def funTester = new FunTester()
        funTester.metaClass.test = {
            logger.info("我是测试方法:{}","static.test")
        }
        funTester.test()

控制台输出:

INFO-> main 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> main 我是测试方法:static.test

Process finished with exit code 0
添加属性
        funTester.metaClass.setProperty("name","FunTester")
        logger.info(funTester.getProperty("name"))

控制台输出:

INFO-> main 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> main FunTester

Process finished with exit code 0

FunTester类代码:

    private static class FunTester {

    }
Spock单元测试

下面使用Spock单元测试框架进行测试,有兴趣的可以看看之前的文章:

代码如下:

package com.funtest.spock


import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import spock.lang.Shared

class Mop extends spock.lang.Specification {

    @Shared
    private static final Logger logger = LogManager.getLogger(Mop.class);

    def setup() {
        logger.info("测试方法开始了")
    }

    def cleanup() {
        logger.info("测试方法结束了")
    }

    def setupSpec() {
        fun.metaClass.getName() {
            def property = fun.getProperty("name")
            logger.warn("获取" + property)
            return property
        }
        fun.metaClass.setName = {x ->
            logger.warn("设置" + x)
            fun.metaClass.setProperty("name", x)
            return fun.getName()
        }
        logger.info("测试类[${getClass().getName()}]开始了")
    }

    def cleanupSpec() {
        logger.info("测试类[${getClass().getName()}]结束了")
    }


    @Shared
    def fun = new Mop()

    def "测试动态添加对象方法"() {
        given:
        fun.metaClass.ob_method = {return 12}
        expect:
        12 == fun.ob_method()
    }


    def "测试动态添加静态方法"() {
        given:
        Mop.metaClass.static.clas_method = {return 12}
        expect:
        12 == Mop.clas_method()
    }

    def "测试动态添加获取属性"() {
        expect:
        fun.setName(name) == tt

        where:
        name        | tt
        "FunTester" | "FunTester"
        "Have Fun"  | "Have Fun"
    }

}


控制台输出:


> Task :test FAILED
INFO-> Test worker 测试类[com.funtest.spock.Mop]开始了
INFO-> Test worker 测试方法开始了
INFO-> Test worker 测试方法结束了
INFO-> Test worker 测试方法开始了
INFO-> Test worker 测试方法结束了
INFO-> Test worker 测试方法开始了
WARN-> Test worker 设置FunTester
WARN-> Test worker 获取FunTester
INFO-> Test worker 测试方法结束了
INFO-> Test worker 测试方法开始了
WARN-> Test worker 设置Have Fun
WARN-> Test worker 获取FunTester
INFO-> Test worker 测试方法结束了

Condition not satisfied:

fun.setName(name) == tt
|   |       |     |  |
|   |       |     |  Have Fun
|   |       |     false
|   |       |     8 differences (11% similarity)
|   |       |     (FunT)e(ster)
|   |       |     (Hav-)e( Fun)
|   |       Have Fun
|   FunTester
<com.funtest.spock.Mop@49013545 $spock_sharedField_fun=null specificationContext=org.spockframework.runtime.SpecificationContext@6c68765>

	at com.funtest.spock.Mop.测试动态添加获取属性(Mop.groovy:60)


INFO-> Test worker 测试类[com.funtest.spock.Mop]结束了

Mop > 测试动态添加对象方法 PASSED
Mop > 测试动态添加静态方法 PASSED
Mop > 测试动态添加获取属性 > com.funtest.spock.Mop.测试动态添加获取属性 [name: FunTester, tt: FunTester, #0] PASSED
Mop > 测试动态添加获取属性 > com.funtest.spock.Mop.测试动态添加获取属性 [name: Have Fun, tt: Have Fun, #1] FAILED
    org.spockframework.runtime.SpockComparisonFailure at Mop.groovy:60
Mop > 测试动态添加获取属性 FAILED
5 tests completed, 2 failed
FAILURE: Build failed with an exception.
4 actionable tasks: 1 executed, 3 up-to-date

Have Fun ~ Tester !

免责声明:文章转载自《Groovy动态添加方法和属性及Spock单测》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇POI 设置Excel单元格背景色(setFillForegroundColor)Java中文乱码原因下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Oracle树查询,start with connect by prior 递归查询用法(转载)

本人觉得这个写的真不错,实用性强,就转载过来了 这个子句主要是用于B树结构类型的数据递归查询,给出B树结构类型中的任意一个结点,遍历其最终父结点或者子结点。 先看原始数据: 1 create table a_test 2 ( parentid varchar2(10), 3 subid varchar2(10)); 4 5 ins...

opensips搭建问题解决笔记

只是笔记而已,不是很详细,莫怪 opensips搭建问题解决笔记:# opensipsctl startINFO: Starting OpenSIPS :ERROR: PID file /var/run/opensips.pid does not exist -- OpenSIPS start failed Nov 6 15:57:53 webcon201...

stacking算法原理及代码

stacking算法原理 1:对于Model1,将训练集D分为k份,对于每一份,用剩余数据集训练模型,然后预测出这一份的结果 2:重复上面步骤,直到每一份都预测出来。得到次级模型的训练集 3:得到k份测试集,平均后得到次级模型的测试集 4:对于Model2、Model3…..重复以上情况,得到M维数据 5:选定次级模型,进行训练预测,一般这最后一...

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

http://blog.csdn.net/zouxy09/article/details/20319673 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression) zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习算法与Python实践这个系列主要是参考《机器学习实战》这本书...

Python-单元测试 unittest &amp;amp; HTMLTestRunner模块产生的测试报告

 1、单元测试: ——开发程序的人测已经已经写好的代码。 unittest框架,执行的顺序是按照方法名的字母来排序的 setUpClass方法是最开始执行的,只会执行一次 tearDownClass是最后执行的,只会执行一次 setUp方法是在每个测试用例执行前会执行 tearDown方法是在每个用例执行后会执行 import unittest de...

不修改sql文本情況下,改變其執行計劃

不修改sql文本情況下,改變其執行計劃 可以使用sql profile和spm(sql plan manage),本文主要介紹SPM方式 sql profile參考sql profile固定執行計劃 步驟 1.手動生成SQL Plan Baseline DECLARE V_TEMP NUMBER; BEGIN V_TEMP :=...