31.Go语言·反射·测试用例

2019-06-13  本文已影响0人  一枼落知天下

xxx_test.go

package test

import (
    "testing"
    "reflect"
)

type user struct {
    UserId string
    Name string
}


type Cal struct {
    Num1 int
    Num2 int
}


func (this *Cal) GetSub(name string,t *testing.T) {
    t.Log("绑定引用类型  (this *Cal) GetSub")
    t.Logf("%v完成咯减法运算,%v-%v=%v ",name,this.Num1,this.Num2,this.Num1-this.Num2)
}

func (this Cal) Atest(t *testing.T) {
    t.Log("绑定值类型的 (this Cal) Atest()")
}

/**
 * [TestReflectStructCal]
 * @author Jhou Shuai
 * @datetime 2019-06-13T10:48:01+0800
 * go test -v -test.run TestReflectStructCal
 */
func TestReflectStructCal(t *testing.T) {
    var (
        model *Cal
        reflectVal reflect.Value
    )

    model = &Cal{}
    reflectVal = reflect.ValueOf(model)
    // reflect.ValueOf: ptr
    t.Log("reflect.ValueOf:",reflectVal.Kind().String()) 
    // user_test.go:45: reflect.ValueOf.Elem: struct
    t.Log("reflect.ValueOf.Elem:",reflectVal.Elem().Kind().String()) 
    
    reflectVal.Elem().FieldByName("Num1").SetInt(100)
    reflectVal.Elem().FieldByName("Num2").SetInt(50)
    t.Log("model:",model)  // 

    // 获取到该结构体有多少个方法
    numMethod := reflectVal.NumMethod()
    t.Log("numMethod:",numMethod)
    // reflect.Value 类型切片
    //温馨提示:
    //若方法绑定类型是指针 (this *Cal) GetSub 直接用指针类型调用
    reflectVal.Method(1).Call([]reflect.Value{reflect.ValueOf("Faker蜗壳儿"),reflect.ValueOf(t)})  

    //若法绑定类型值类型,(this Cal) Zoom 这需要reflectVal.Elem()--》reflect.Value 类型
    reflectVal.Elem().Method(0).Call([]reflect.Value{reflect.ValueOf(t)})
}



/**
 * [TestReflectStructHandle]
 * 使用反射操作任意结构体类型
 * @author Jhou Shuai
 * @datetime 2019-06-13T10:48:01+0800
 * go test -v -test.run TestReflectStructHandle
 */
func TestReflectStructHandle(t *testing.T) {
    var (
        model *user
        reflectVal reflect.Value
    )

    model = &user{}
    reflectVal = reflect.ValueOf(model)
    t.Log("reflect.ValueOf:",reflectVal.Kind().String()) //ptr
    reflectVal = reflectVal.Elem()
    t.Log("reflect.ValueOf.Elem:",reflectVal.Kind().String()) //struct
    reflectVal.FieldByName("UserId").SetString("No.9527")
    reflectVal.FieldByName("Name").SetString("凌凌漆")
    t.Log("model:",model)  // &{No.9527 凌凌漆}
}


/**
 * [TestReflectStructPtr]
 * 使用反射创建并操作结构体
 * @author Jhou Shuai
 * @datetime 2019-06-13T10:45:52+0800
 * go test -v -test.run TestReflectStructPtr
 */
func TestReflectStructPtr(t *testing.T) {
    var(
        model *user
        reflectType reflect.Type
        reflectVal reflect.Value
    )

    // 获取类型*user
    reflectType = reflect.TypeOf(model)
    t.Log("reflect.TypOf:",reflectType.Kind().String()) //ptr
    reflectType = reflectType.Elem() 
    t.Log("reflect.TypOf.Elem:",reflectType.Kind().String()) //struct
    
    // New返回一个Value类型值,
    // 该值持有一个指向类型为typ的新申请的零值指针
    reflectVal = reflect.New(reflectType)
    t.Log("reflect.New:",reflectVal.Kind().String()) //ptr
    t.Log("reflect.New.Elem:",reflectVal.Elem().Kind().String()) //struct

    // model就是创建的user结构体变量(实例)
    // 类型断言 ---》指向*user
    model = reflectVal.Interface().(*user) 

    // 取到reflectVal指向的值---》*user
    reflectVal = reflectVal.Elem() 

    // model 跟 reflectVal ---》*user
    // model是*user的指向和reflectVal是一样的

    // 赋值
    reflectVal.FieldByName("UserId").SetString("No.120988")
    reflectVal.FieldByName("Name").SetString("小可爱")
    t.Log("model.UserId:",model.UserId)
    t.Log("model.Name:",model.Name)
}

/**
 * [TestApplicaion ]
 * 定义一个适配器函数用作统一处理接口
 * @author Jhou Shuai
 * @datetime 2019-06-13T11:06:38+0800
 * go test -v -test.run TestApplicaion
 */
func TestApplicaion(t *testing.T) {
    test1:= func(v1 int,v2 int){
        t.Log(v1,v2)
    }

    test2:= func(v1 int,v2  int,s string){
        t.Log(v1,v2,s)
    }

    var (
        function reflect.Value
        inValue []reflect.Value
        n  int
    )

    bridge := func(call interface{},args...interface{}){
        // 参数个数
        n = len(args)
        inValue =make([]reflect.Value, n)
        for i := 0; i <n; i++ {
            inValue[i] = reflect.ValueOf(args[i])
        }

        function = reflect.ValueOf(call)
        function.Call(inValue)
    }

    bridge(test1,1,2)
    bridge(test2,1,2,"test2")
}
上一篇 下一篇

猜你喜欢

热点阅读