github.com/tencent/goom@v1.0.1/var.go (about)

     1  package mocker
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/tencent/goom/internal/logger"
     8  )
     9  
    10  // VarMock 变量 mock
    11  // 支持全局变量, 任意类型包括不限于基本类型,结构体,函数变量,指针与非指针类型
    12  // 主要提供方便变量 mock/reset 场景的能力支持
    13  type VarMock interface {
    14  	Mocker
    15  	// Set 设置变量值, val 类型必须和变量指针指向的值的类型一致
    16  	Set(val interface{})
    17  }
    18  
    19  // defaultVarMocker 默认变量 mock 实现
    20  type defaultVarMocker struct {
    21  	target      interface{}
    22  	mockValue   interface{}
    23  	originValue interface{}
    24  	canceled    bool // canceled 是否被取消
    25  }
    26  
    27  // String mock 的名称或描述, 方便调试和问题排查
    28  func (m *defaultVarMocker) String() string {
    29  	return fmt.Sprintf("var at[%d]", reflect.ValueOf(m.target).Pointer())
    30  }
    31  
    32  // NewVarMocker 创建 VarMock
    33  func NewVarMocker(target interface{}) VarMock {
    34  	t := reflect.ValueOf(target)
    35  	if t.Type().Kind() != reflect.Ptr {
    36  		panic("VarMock target must be a pointer.")
    37  	}
    38  	return &defaultVarMocker{
    39  		target:   target,
    40  		canceled: false,
    41  	}
    42  }
    43  
    44  // Apply 变量取值回调函数, 只会执行一次
    45  // 注意: Apply 会覆盖之前设定 Set 的值
    46  func (m *defaultVarMocker) Apply(callback interface{}) {
    47  	f := reflect.ValueOf(callback)
    48  	if f.Kind() != reflect.Func {
    49  		panic("VarMock Apply argument(callback) must be a func.")
    50  	}
    51  	ret := f.Call([]reflect.Value{})
    52  	if ret == nil || len(ret) != 1 {
    53  		panic("VarMock Apply callback's returns length must be 1.")
    54  	}
    55  
    56  	m.doSet(ret[0].Interface())
    57  	logger.Consolefc(logger.DebugLevel, "mocker [%s] apply.", logger.Caller(5), m.String())
    58  }
    59  
    60  // Cancel 取消 mock
    61  func (m *defaultVarMocker) Cancel() {
    62  	t := reflect.ValueOf(m.target)
    63  	t.Elem().Set(reflect.ValueOf(m.originValue))
    64  	m.canceled = true
    65  }
    66  
    67  // Canceled 是否取消了 mock
    68  func (m *defaultVarMocker) Canceled() bool {
    69  	return m.canceled
    70  }
    71  
    72  // Set 设置变量值
    73  // 注意: Set 会覆盖之前设定 Apply 的值
    74  func (m *defaultVarMocker) Set(value interface{}) {
    75  	m.doSet(value)
    76  	logger.Consolefc(logger.DebugLevel, "mocker [%s] apply.", logger.Caller(5), m.String())
    77  }
    78  
    79  func (m *defaultVarMocker) doSet(value interface{}) {
    80  	t := reflect.ValueOf(m.target)
    81  	m.originValue = t.Elem().Interface()
    82  	d := reflect.ValueOf(value)
    83  	t.Elem().Set(d)
    84  	m.mockValue = value
    85  }