前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Groovy动态添加方法和属性及Spock单测

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

作者头像
FunTester
发布2021-11-04 11:22:31
发布2021-11-04 11:22:31
99400
代码可运行
举报
文章被收录于专栏:FunTesterFunTester
运行总次数:0
代码可运行

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

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

添加对象方法

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

代码语言:javascript
代码运行次数:0
复制
        def funTester = new FunTester()
        funTester.metaClass.test = {
            logger.info("我是测试方法:{}","test")
        }
        funTester.test()

控制台输出:

代码语言:javascript
代码运行次数:0
复制
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 = {闭包},如下:

代码语言:javascript
代码运行次数:0
复制
        def funTester = new FunTester()
        funTester.metaClass.test = {
            logger.info("我是测试方法:{}","static.test")
        }
        funTester.test()

控制台输出:

代码语言:javascript
代码运行次数:0
复制
INFO-> main 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> main 我是测试方法:static.test

Process finished with exit code 0

添加属性

代码语言:javascript
代码运行次数:0
复制
        funTester.metaClass.setProperty("name","FunTester")
        logger.info(funTester.getProperty("name"))

控制台输出:

代码语言:javascript
代码运行次数:0
复制
INFO-> main 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> main FunTester

Process finished with exit code 0

FunTester类代码:

代码语言:javascript
代码运行次数:0
复制
    private static class FunTester {

    }

Spock单元测试

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

代码如下:

代码语言:javascript
代码运行次数:0
复制
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"
    }

}


控制台输出:

代码语言:javascript
代码运行次数:0
复制

> 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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加对象方法
  • 添加静态方法
  • 添加属性
  • Spock单元测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档