mocker

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 19, 2023 License: MIT Imports: 14 Imported by: 0

README

GOOM单测Mock框架

介绍

背景
  1. 基于公司目前内部没有一款自己维护的适合公司业务迭代速度和稳定性要求的mock框架,众多项目采用外界开源的gomonkey框架进行函数的mock,因其存在较一些的bug,不支持异包未导出函数mock,同包未导出方法mock等等问题, 加上团队目前实现一款改进版-无需unpath即可在mock过程中调用原函数的特性,可以支持到延迟模拟,参数更改,mock数据录制等功能,因此建立此项目
  2. 目前有一半以上方案是基于gomock类似的实现方案, 此mock方案需要要求业务代码具备良好的接口设计,才能顺利生成mock代码,而goom只需要指定函数名称或函数定义,就能支持到任意函数的mock,任意函数异常注入,延时模拟等扩展性功能
功能特性
  1. mock过程中调用原函数(线程安全, 支持并发单测)
  2. 异常注入,对函数调用支持异常注入,延迟模拟等稳定性测试
  3. 所有操作都是并发安全的
  4. 未导出(未导出)函数(或方法)的mock(不建议使用, 对于未导出函数的Mock 通常都是因为代码设计可能有问题, 此功能会在未来版本中废弃)
  5. 支持M1 mac环境运行,支持IDE debug,函数、方法mock,接口mock,未导出函数mock,等能力均可在arm64架构上使用
将来
  1. 支持数据驱动测试
  2. 支持Mock锚点定义
  3. 支持代码重构

注意!!!不要过度依赖mock

1.千万不要过度依赖于mock

2.对于正规的第三方库,比如mysql、gorm的库本身会提供mock能力, 可参考sql_test.go

3.对于自建的内部依赖库, 建议由库的提供方编写mock(1.使用方无需关心提供方的实现细节、2.由库提供方负责版本升级时mock实现逻辑的更新)

Install

# 支持的golang版本: go1.11-go1.18
go get github.com/tencent/goom

Tips

注意: 按照go编译规则,短函数会被内联优化,导致无法mock的情况,编译参数需要加上 -gcflags=all=-l 关闭内联
例如: go test -gcflags=all=-l hello.go

Getting Start

// 在需要使用mock的测试文件import
import "github.com/tencent/goom"
1. 基本使用
1.1. 函数mock
// foo 函数定义如下
func foo(i int) int {
    //...
    return 0
}

// mock示例
// 创建当前包的mocker
mock := mocker.Create()

// mock函数foo并设定返回值为1
mock.Func(foo).Return(1)
s.Equal(1, foo(0), "return result check")

// 可搭配When使用: 参数匹配时返回指定值
mock.Func(foo).When(1).Return(2)
s.Equal(2, foo(1), "when result check")

// 使用arg.In表达式,当参数为1、2时返回值为100
mock.Func(foo).When(arg.In(1, 2)).Return(100)
s.Equal(100, foo(1), "when in result check")
s.Equal(100, foo(2), "when in result check")

// 按顺序依次返回(等价于gomonkey的Sequence)
mock.Func(foo).Returns(1, 2, 3)
s.Equal(1, foo(0), "returns result check")
s.Equal(2, foo(0), "returns result check")
s.Equal(3, foo(0), "returns result check")

// mock函数foo,使用Apply方法设置回调函数
// 注意: Apply和直接使用Return都可以实现mock,两种方式二选一即可
// Apply可以在桩函数内部实现自己的逻辑,比如根据不同参数返回不同值等等。
mock.Func(foo).Apply(func(int) int {
    return 1
})
s.Equal(1, foo(0), "apply callback check")


// bar 多参数函数
func bar(i interface{}, j int) int {
    //...
    return 0
}

// 忽略第一个参数, 当第二个参数为1、2时返回值为100
mock.Func(bar).When(arg.Any(), arg.In(1, 2)).Return(100)
s.Equal(100, bar(-1, 1), "any param result check")
s.Equal(100, bar(0, 1), "any param result check")
s.Equal(100, bar(1, 2), "any param result check")
s.Equal(100, bar(999, 2), "any param result check")
1.2. 结构体方法mock
// 结构体定义如下
type Struct1 struct{
}

// Call 导出方法
func (f *Struct1) Call(i int) int {
    return i
}

// mock示例
// 创建当前包的mocker
mock := mocker.Create()

// mock 结构体Struct1的方法Call并设置其回调函数
// 注意: 当使用Apply方法时,如果被mock对象为结构体方法, 那么Apply参数func()的第一个参数必须为接收体(即结构体/指针类型)
// 其中, func (f *Struct1) Call(i int) int 和 &Struct1{} 与 _ *Struct1同时都是带指针的接受体类型, 需要保持一致
mock.Struct(&Struct1{}).Method("Call").Apply(func(_ *Struct1, i int) int {
    return i * 2
 })

// mock 结构体struct1的方法Call并返回1
// 简易写法直接Return方法的返回值, 无需关心方法签名
mock.Struct(&Struct1{}).Method("Call").Return(1)
1.3. 结构体的未导出方法mock

// call 未导出方法示例
func (f *Struct1) call(i int) int {
    return i
}

// mock 结构体Struct1的未导出方法call, mock前先调用ExportMethod将其导出,并设置其回调函数
mock.Struct(&Struct1{}).ExportMethod("call").Apply(func(_ *Struct1, i int) int {
    return i * 2
})

// mock 结构体Struct1的未导出方法call, mock前先调用ExportMethod将其导出为函数类型,后续支持设置When, Return等
// As调用之后,请使用Return或When API的方式来指定mock返回。
mock.Struct(&Struct1{}).ExportMethod("call").As(func(_ *Struct1, i int) int {
    // 随机返回值即可; 因后面已经使用了Return,此函数不会真正被调用, 主要用于指定未导出函数的参数签名
    return i * 2
}).Return(1)
2. 接口Mock

接口定义举例:

// I 接口测试
type I interface {
  Call(int) int
  Call1(string) string
  call2(int32) int32
}

被测接口实例代码:

// TestTarget 被测对象
type TestTarget struct {
	// field 被测属性(接口类型)
	field I
}

func NewTestTarget(i I) *TestTarget {
	return &TestTarget{
		field:i,
	}
}

func (t *TestTarget) Call(num int) int {
	return field.Call(num)
}

func (t *TestTarget) Call1(str string) string {
    return  field.Call1(str)
}

接口属性/变量Mock示例:

mock := mocker.Create()

// 初始化接口变量
i := (I)(nil)

// 将Mock应用到接口变量
// 1. interface mock只对mock.Interface(&目标接口变量) 的目标接口变量生效, 因此需要将被测逻辑结构中的I类型属性或变量替换为i,mock才可生效
// 2. 一般建议使用struct mock即可。
// 3. Apply调用的第一个参数必须为*mocker.IContext, 作用是指定接口实现的接收体; 后续的参数原样照抄。
mock.Interface(&i).Method("Call").Apply(func(ctx *mocker.IContext, i int) int {
    return 100
})

// ===============================================================================
// !!! 如果是mock interface的话,需要将interface i变量赋值替换【被测对象】的【属性】,才能生效
// 也就是说,不对该接口的所有实现类实例生效。
t := NewTestTarget(i)

// 断言mock生效
s.Equal(100, t.Call(1), "interface mock check")

mock.Interface(&i).Method("Call1").As(func(ctx *mocker.IContext, i string) string {
    // 随机返回值即可; 因后面已经使用了Return,此函数不会真正被调用, 主要用于指定未导出函数的参数签名
	return ""
}).When("").Return("ok")
s.Equal("ok", t.Call1(""), "interface mock check")

// Mock重置, 接口变量将恢复原来的值
mock.Reset()
s.Equal(nil, i, "interface mock reset check")
3. 高阶用法
3.1. 外部package的未导出函数mock(一般不建议对不同包下的未导出函数进行mock)
// 针对其它包的mock示例
// 创建指定包的mocker,设置引用路径
mock := mocker.Create()

// mock函数foo1并设置其回调函数
mock.Pkg("github.com/tencent/goom_test").ExportFunc("foo1").Apply(func(i int) int {
    return i * 3
})

// mock函数foo1并设置其返回值
mock.ExportFunc("foo1").As(func(i int) int {
    // 随机返回值即可; 因后面已经使用了Return,此函数不会真正被调用, 主要用于指定未导出函数的参数签名
    return 0
}).Return(1)
3.2. 外部package的未导出结构体的mock(一般不建议对不同包下的未导出结构体进行mock)
// 针对其它包的mock示例
package https://github.com/tencent/goom/a

// struct2 要mock的目标结构体
type struct2 struct {
    field1 <type>
    // ...
}

Mock代码示例:

package https://github.com/tencent/goom/b

// fake fake一个结构体, 用于作为回调函数的Receiver
type fake struct {
    // fake结构体要和原未导出结构体的内存结构对齐
    // 即: 字段个数、顺序、类型必须一致; 比如: field1 <type> 如果有
    // 此结构体无需定义任何方法
	field1 <type>
    // ...
}

// 创建指定包的mocker,设置引用路径
mock := mocker.Create()

// mock其它包的未导出结构体struct2的未导出方法call,并设置其回调函数
// 如果参数是未导出的,那么需要在当前包fake一个同等结构的struct(只需要fake结构体,方法不需要fake),fake结构体要和原未导出结构体struct2的内存结构对齐
// 注意: 如果方法是指针方法,那么需要给struct加上*,比如:ExportStruct("*struct2")
mock.Pkg("https://github.com/tencent/goom/a").ExportStruct("struct2").Method("call").Apply(func(_ *fake, i int) int {
    return 1
})
s.Equal(1, struct2Wrapper.call(0), "unexported struct mock check")

// mock其它包的未导出结构体struct2的未导出方法call,并设置其返回值
mock.ExportStruct("struct2").Method("call").As(func(_ *fake, i int) int {
	// 随机返回值即可; 因后面已经使用了Return,此函数不会真正被调用, 主要用于指定接口方法的参数签名
    return 0
}).Return(1) // 指定返回值
s.Equal(1, struct2Wrapper.call(0), "unexported struct mock check")
4. 追加多个返回值序列
mock := mocker.Create()

// 设置函数foo当传入参数为1时,第一次返回3,第二次返回2
when := mock.Func(foo).When(1).Return(0)
for i := 1;i <= 100;i++ {
    when.AndReturn(i)
}
s.Equal(0, foo(1), "andReturn result check")
s.Equal(1, foo(1), "andReturn result check")
s.Equal(2, foo(1), "andReturn result check")
 ...
5. 在回调函数中调用原函数
mock := mocker.Create()

// 定义原函数,用于占位,实际不会执行该函数体
// 需要和原函数的参数列表保持一致
// 定义原函数,用于占位,实际不会执行该函数体
var origin = func(i int) int {
    // 用于占位, 实际不会执行该函数体; 因底层trampoline技术的占位要求, 必须编写方法体
    fmt.Println("only for placeholder, will not call")
    // return 指定随机返回值即可
    return 0
}

mock.Func(foo1).Origin(&origin).Apply(func(i int) int {
    // 调用原函数
    originResult := origin(i)

    // 加入延时逻辑等
    time.Sleep(time.Seconds)

    return originResult + 100
})
// foo1(1) 等待1秒之后返回:101
s.Equal(101, foo1(1), "call origin result check")

问题答疑

问题答疑记录wiki地址 常见问题:

  1. 如果是M1-MAC(arm CPU)机型, 可以尝试以下两种方案

a. 尝试使用权限修复工具,在项目根目录执行以下指令:

MOCKER_DIR=$(go list -m -f '{{.Dir}}' github.com/tencent/goom)
${MOCKER_DIR}/tool/permission_denied.sh -i

b: 如果a方案没有效果,则尝试切换成amd的go编译器,在环境变量中添加:

GOARCH=amd64
  1. 如果遇到mock未生效的问题,可以打开debug日志进行自助排查
// TestUnitTestSuite 测试入口
func TestUnitTestSuite(t *testing.T) {
	// 开启debug模式, 在控制台可以
	// 1.查看apply和reset的状态日志
	// 2.查看mock调用日志
	mocker.OpenDebug()
	suite.Run(t, new(mockerTestSuite))
}

Contributor

@yongfuchen、@adrewchen、@ivyyi、@miliao

Documentation

Overview

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件实现了 Mocker 接口各实现类的构造链创建,以便通过链式构造一个 Mocker 对象。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件实现了当对同一方法或函数名进行重复构造时可以沿用缓存中已建好的 Mocker, 以防止在一个单测内重复构造 Mocker 时, 对上一个相同函数或方法的 Mocker 的内容规则造成覆盖。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件实现了 mock 守卫能力, 不同类型的 Mocker 具备不一样的 Apply、Cancel 具体行为,本 MockGuard 抽象了统一各类 Mocker 的 Guard, 以供 BaseMocker 使用其接口类 MockGuard 的 Apply、Cancel 方法。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件实现了接口 mock 的能力。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件定义了函数、方法、未导出函数(或方法)的 Mocker 的行为。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件汇聚了公共的工具类,比如类型转换。

Package mocker 定义了 mock 的外层用户使用 API 定义, 包括函数、方法、接口、未导出函数(或方法的)的 Mocker 的实现。 当前文件实现了按照参数条件进行匹配, 返回对应的 mock return 值, 支持了 mocker.When(XXX).Return(YYY)的高效匹配。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloseDebug

func CloseDebug()

CloseDebug 关闭 debug 模式

func CloseTrace

func CloseTrace()

CloseTrace 关闭日志跟踪

func OpenDebug

func OpenDebug()

OpenDebug 开启 debug 模式 也可以通过添加环境变量开启 debug: GOOM_DEBUG=true 1.可以查看 apply 和 reset 的状态日志 2.查看 mock 调用日志

func OpenTrace

func OpenTrace()

OpenTrace 打开日志跟踪

Types

type AlwaysMatcher

type AlwaysMatcher struct {
	*BaseMatcher
}

AlwaysMatcher 默认匹配

func (*AlwaysMatcher) Match

func (c *AlwaysMatcher) Match(_ []reflect.Value) bool

Match 总是匹配

type BaseMatcher

type BaseMatcher struct {
	// contains filtered or unexported fields
}

BaseMatcher 参数匹配基类

func (*BaseMatcher) AddResult

func (c *BaseMatcher) AddResult(results []interface{})

AddResult 添加结果

func (*BaseMatcher) Result

func (c *BaseMatcher) Result() []reflect.Value

Result 回参

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder Mock 构建器, 负责创建一个链式构造器.

func Create

func Create() *Builder

Create 创建 Mock 构建器 非线程安全的,不能在多协程中并发地 mock 或 reset 同一个函数

func (*Builder) ExportFunc

func (b *Builder) ExportFunc(name string) *UnexportedFuncMocker

ExportFunc 导出私有函数 比如需要 mock 函数 foo(), 则 name="pkg_name.foo" 比如需要 mock 方法, pkg_name.(*struct_name).method_name name string foo 或者(*struct_name).method_name

func (*Builder) ExportStruct

func (b *Builder) ExportStruct(name string) *CachedUnexportedMethodMocker

ExportStruct 导出私有结构体 比如需要 mock 结构体函数 (*conn).Write(b []byte),则 name="conn"

func (*Builder) Func

func (b *Builder) Func(funcDef interface{}) *DefMocker

Func 指定函数定义 funcDef 函数,比如 foo 方法的 mock, 比如 &Struct{}.method

func (*Builder) Interface

func (b *Builder) Interface(iFace interface{}) *CachedInterfaceMocker

Interface 指定接口类型的变量定义 iFace 必须是指针类型, 比如 i 为 interface 类型变量, iFace 传递&i

func (*Builder) Pkg

func (b *Builder) Pkg(name string) *Builder

Pkg 指定包名,当前包无需指定 对于跨包目录的私有函数的 mock 通常都是因为代码设计可能有问题, 此功能会在未来版本中移除 后续仅支持同包下的未导出方法的 mock Deprecated: 对于跨包目录的私有函数的 mock 通常都是因为代码设计可能有问题

func (*Builder) PkgName

func (b *Builder) PkgName() string

PkgName 返回包名 Deprecated: 对于跨包目录的私有函数的 mock 通常都是因为代码设计可能有问题

func (*Builder) Reset

func (b *Builder) Reset() *Builder

Reset 取消当前 builder 的所有 Mock

func (*Builder) Struct

func (b *Builder) Struct(instance interface{}) *CachedMethodMocker

Struct 指定结构体实例 比如需要 mock 结构体函数 (*conn).Write(b []byte),则 name="conn"

func (*Builder) Var

func (b *Builder) Var(v interface{}) VarMock

Var 变量 mock, target 类型必须传递指针类型

type CachedInterfaceMocker

type CachedInterfaceMocker struct {
	*DefaultInterfaceMocker
	// contains filtered or unexported fields
}

CachedInterfaceMocker 带缓存的 Interface Mocker

func NewCachedInterfaceMocker

func NewCachedInterfaceMocker(interfaceMocker *DefaultInterfaceMocker) *CachedInterfaceMocker

NewCachedInterfaceMocker 创建新的带缓存的 Interface Mocker

func (*CachedInterfaceMocker) Cancel

func (m *CachedInterfaceMocker) Cancel()

Cancel 取消 mock

func (*CachedInterfaceMocker) Canceled

func (m *CachedInterfaceMocker) Canceled() bool

Canceled 是否取消了 mock

func (*CachedInterfaceMocker) Method

Method 指定方法名

func (*CachedInterfaceMocker) String

func (m *CachedInterfaceMocker) String() string

String mock 的名称或描述

type CachedMethodMocker

type CachedMethodMocker struct {
	*MethodMocker
	// contains filtered or unexported fields
}

CachedMethodMocker 带缓存的方法 Mocker,将同一个函数或方法的 Mocker 进行 cache

func NewCachedMethodMocker

func NewCachedMethodMocker(m *MethodMocker) *CachedMethodMocker

NewCachedMethodMocker 创建新的带缓存的方法 Mocker

func (*CachedMethodMocker) Cancel

func (m *CachedMethodMocker) Cancel()

Cancel 取消 mock

func (CachedMethodMocker) Canceled

func (m CachedMethodMocker) Canceled() bool

Canceled 是否被取消

func (*CachedMethodMocker) ExportMethod

func (m *CachedMethodMocker) ExportMethod(name string) UnExportedMocker

ExportMethod 导出私有方法

func (*CachedMethodMocker) Method

func (m *CachedMethodMocker) Method(name string) ExportedMocker

Method 设置结构体的方法名

func (*CachedMethodMocker) String

func (m *CachedMethodMocker) String() string

String mock 的名称

type CachedUnexportedMethodMocker

type CachedUnexportedMethodMocker struct {
	*UnexportedMethodMocker
	// contains filtered or unexported fields
}

CachedUnexportedMethodMocker 带缓存的未导出方法 Mocker

func NewCachedUnexportedMethodMocker

func NewCachedUnexportedMethodMocker(m *UnexportedMethodMocker) *CachedUnexportedMethodMocker

NewCachedUnexportedMethodMocker 创建新的带缓存的未导出方法 Mocker

func (*CachedUnexportedMethodMocker) Cancel

func (m *CachedUnexportedMethodMocker) Cancel()

Cancel 清除 mock

func (CachedUnexportedMethodMocker) Canceled

func (m CachedUnexportedMethodMocker) Canceled() bool

Canceled 是否被取消

func (*CachedUnexportedMethodMocker) Method

Method 设置结构体的方法名

func (*CachedUnexportedMethodMocker) String

String mock 的名称或描述

type ContainsMatcher

type ContainsMatcher struct {
	*BaseMatcher
	// contains filtered or unexported fields
}

ContainsMatcher 包含类型的参数匹配 当参数为多个时, In 的每个条件各使用一个数组表示: .In([]interface{}{3, Any()}, []interface{}{4, Any()})

func (*ContainsMatcher) Match

func (c *ContainsMatcher) Match(args []reflect.Value) bool

Match 判断是否匹配

type DefMocker

type DefMocker struct {
	// contains filtered or unexported fields
}

DefMocker 对函数或方法进行 mock,使用函数定义筛选

func NewDefMocker

func NewDefMocker(pkgName string, funcDef interface{}) *DefMocker

NewDefMocker 创建 DefMocker pkgName 包路径 funcDef 函数变量定义

func (*DefMocker) Apply

func (m *DefMocker) Apply(callback interface{})

Apply 代理方法实现

func (DefMocker) Cancel

func (m DefMocker) Cancel()

Cancel 取消 Mock

func (DefMocker) Canceled

func (m DefMocker) Canceled() bool

Canceled 是否被取消

func (*DefMocker) Origin

func (m *DefMocker) Origin(originFunc interface{}) ExportedMocker

Origin 调用原函数 origin 需要和原函数的参数列表保持一致

func (*DefMocker) Return

func (m *DefMocker) Return(value ...interface{}) *When

Return 代理方法返回

func (*DefMocker) Returns

func (m *DefMocker) Returns(values ...interface{}) *When

Returns 依次按顺序返回值, 如果是多参可使用[]interface{}

func (*DefMocker) String

func (m *DefMocker) String() string

String mock 的名称或描述

func (*DefMocker) When

func (m *DefMocker) When(specArg ...interface{}) *When

When 指定条件匹配

type DefaultInterfaceMocker

type DefaultInterfaceMocker struct {
	// contains filtered or unexported fields
}

DefaultInterfaceMocker 默认接口 Mocker

func NewDefaultInterfaceMocker

func NewDefaultInterfaceMocker(pkgName string, iFace interface{}, ctx *iface.IContext) *DefaultInterfaceMocker

NewDefaultInterfaceMocker 创建默认接口 Mocker pkgName 包路径 iFace 接口变量定义

func (*DefaultInterfaceMocker) Apply

func (m *DefaultInterfaceMocker) Apply(callback interface{})

Apply 应用接口方法 mock 为实际的接收体方法 callback 函数的第一个参数必须为*mocker.IContext, 作用是指定接口实现的接收体; 后续的参数原样照抄。

func (*DefaultInterfaceMocker) As

func (m *DefaultInterfaceMocker) As(aFunc interface{}) InterfaceMocker

As 将接口方法 mock 为实际的接收体方法 aFunc 函数的第一个参数必须为*mocker.IContext, 作用是指定接口实现的接收体; 后续的参数原样照抄。

func (DefaultInterfaceMocker) Cancel

func (m DefaultInterfaceMocker) Cancel()

Cancel 取消 Mock

func (DefaultInterfaceMocker) Canceled

func (m DefaultInterfaceMocker) Canceled() bool

Canceled 是否被取消

func (*DefaultInterfaceMocker) Inject

func (m *DefaultInterfaceMocker) Inject(interface{}) InterfaceMocker

Inject 回调原函数(暂时不支持)

func (*DefaultInterfaceMocker) Method

Method 指定 mock 的方法名

func (*DefaultInterfaceMocker) Origin

func (m *DefaultInterfaceMocker) Origin(interface{}) ExportedMocker

Origin 回调原函数(暂时不支持)

func (*DefaultInterfaceMocker) Return

func (m *DefaultInterfaceMocker) Return(value ...interface{}) *When

Return 指定返回值

func (*DefaultInterfaceMocker) Returns

func (m *DefaultInterfaceMocker) Returns(values ...interface{}) *When

Returns 指定返回多个值

func (*DefaultInterfaceMocker) String

func (m *DefaultInterfaceMocker) String() string

String 接口 Mock 名称

func (*DefaultInterfaceMocker) When

func (m *DefaultInterfaceMocker) When(specArg ...interface{}) *When

When 执行参数匹配时的返回值

type DefaultMatcher

type DefaultMatcher struct {
	*BaseMatcher
	// contains filtered or unexported fields
}

DefaultMatcher 参数匹配 入参个数必须和函数或方法参数个数一致, 比如: When(

In(3, 4), // 第一个参数是 In
Any()) // 第二个参数是 Any

func (*DefaultMatcher) Match

func (c *DefaultMatcher) Match(args []reflect.Value) bool

Match 判断是否匹配

type EmptyMatch

type EmptyMatch struct {
	*AlwaysMatcher
}

EmptyMatch 没有返回参数的匹配器

func (*EmptyMatch) Result

func (c *EmptyMatch) Result() []reflect.Value

Result 返回参数

type ExportedMocker

type ExportedMocker interface {
	Mocker
	// When 指定条件匹配
	When(specArg ...interface{}) *When
	// Return 执行返回值
	Return(value ...interface{}) *When
	// Returns 依次按顺序返回值, 如果是多参可使用[]interface{}
	Returns(values ...interface{}) *When
	// Origin 指定 Mock 之后的原函数, origin 签名和 mock 的函数一致
	Origin(originFunc interface{}) ExportedMocker
}

ExportedMocker 导出函数 mock 接口

type IContext

type IContext struct {
	// Data 可以传递任意数据
	Data interface{}
	// contains filtered or unexported fields
}

IContext 接口 mock 的接收体 和 internal/proxy.IContext 保持同步

type InterfaceMocker

type InterfaceMocker interface {
	ExportedMocker
	// Method 指定接口方法
	Method(name string) InterfaceMocker
	// As 将接口方法应用为函数类型
	// As 调用之后,请使用 Return 或 When API 的方式来指定 mock 返回。
	// aFunc 函数的第一个参数必须为*mocker.IContext, 作用是指定接口实现的接收体; 后续的参数原样照抄。
	As(aFunc interface{}) InterfaceMocker
	// Inject 将 mock 设置到变量
	Inject(iFace interface{}) InterfaceMocker
}

InterfaceMocker 接口 Mock 通过生成和替代接口变量实现 Mock

type Matcher

type Matcher interface {
	// Match 匹配执行方法
	Match(args []reflect.Value) bool
	// Result 匹配成功返回的结果
	Result() []reflect.Value
	// AddResult 添加返回结果
	AddResult([]interface{})
}

Matcher 参数匹配接口

type MethodMocker

type MethodMocker struct {
	// contains filtered or unexported fields
}

MethodMocker 对结构体函数或方法进行 mock 能支持到私有函数、私有类型的方法的 Mock

func NewMethodMocker

func NewMethodMocker(pkgName string, structDef interface{}) *MethodMocker

NewMethodMocker 创建 MethodMocker pkgName 包路径 structDef 结构体变量定义, 不能为 nil

func (*MethodMocker) Apply

func (m *MethodMocker) Apply(callback interface{})

Apply 指定 mock 执行的回调函数 mock 回调函数, 需要和 mock 模板函数的签名保持一致 方法的参数签名写法比如: func(s *Struct, arg1, arg2 type), 其中第一个参数必须是接收体类型

func (MethodMocker) Cancel

func (m MethodMocker) Cancel()

Cancel 取消 Mock

func (MethodMocker) Canceled

func (m MethodMocker) Canceled() bool

Canceled 是否被取消

func (*MethodMocker) ExportMethod

func (m *MethodMocker) ExportMethod(name string) UnExportedMocker

ExportMethod 导出私有方法

func (*MethodMocker) Method

func (m *MethodMocker) Method(name string) ExportedMocker

Method 设置结构体的方法名

func (*MethodMocker) Origin

func (m *MethodMocker) Origin(originFunc interface{}) ExportedMocker

Origin 指定调用的原函数

func (*MethodMocker) Return

func (m *MethodMocker) Return(value ...interface{}) *When

Return 指定返回值

func (*MethodMocker) Returns

func (m *MethodMocker) Returns(values ...interface{}) *When

Returns 依次按顺序返回值

func (*MethodMocker) String

func (m *MethodMocker) String() string

String mock 的名称或描述, 方便调试和问题排查

func (*MethodMocker) When

func (m *MethodMocker) When(specArg ...interface{}) *When

When 指定条件匹配

type MockGuard

type MockGuard interface {
	// Apply 应用 Mock
	Apply()
	// Cancel 取消 Mock
	Cancel()
}

MockGuard Mock 守卫 负责 Mock 应用和取消

type Mocker

type Mocker interface {
	// Apply 代理方法实现
	// 注意: Apply 会覆盖之前设定的 When 条件和 Return
	// 注意: 不支持在多个协程中并发地 Apply 不同的 imp 函数
	Apply(callback interface{})
	// Cancel 取消代理
	Cancel()
	// Canceled 是否已经被取消
	Canceled() bool
	// String mock 的名称或描述, 方便调试和问题排查
	String() string
}

Mocker mock 接口, 所有类型(函数、方法、未导出函数、接口等)的 Mocker 的抽象

type UnExportedMocker

type UnExportedMocker interface {
	Mocker
	// As 将未导出函数(或方法)转换为导出函数(或方法)
	// As 调用之后,请使用 Return 或 When API 的方式来指定 mock 返回。
	As(aFunc interface{}) ExportedMocker
	// Origin 指定 Mock 之后的原函数, origin 签名和 mock 的函数一致
	Origin(originFunc interface{}) UnExportedMocker
}

UnExportedMocker 未导出函数 mock 接口

type UnexportedFuncMocker

type UnexportedFuncMocker struct {
	// contains filtered or unexported fields
}

UnexportedFuncMocker 对函数或方法进行 mock 能支持到私有函数、私有类型的方法的 Mock

func NewUnexportedFuncMocker

func NewUnexportedFuncMocker(pkgName, funcName string) *UnexportedFuncMocker

NewUnexportedFuncMocker 创建未导出函数 Mocker pkgName 包路径 funcName 函数名称

func (*UnexportedFuncMocker) Apply

func (m *UnexportedFuncMocker) Apply(callback interface{})

Apply 指定 mock 执行的回调函数 mock 回调函数, 需要和 mock 模板函数的签名保持一致 方法的参数签名写法比如: func(s *Struct, arg1, arg2 type), 其中第一个参数必须是接收体类型

func (*UnexportedFuncMocker) As

func (m *UnexportedFuncMocker) As(aFunc interface{}) ExportedMocker

As 将未导出函数(或方法)转换为导出函数(或方法)

func (UnexportedFuncMocker) Cancel

func (m UnexportedFuncMocker) Cancel()

Cancel 取消 Mock

func (UnexportedFuncMocker) Canceled

func (m UnexportedFuncMocker) Canceled() bool

Canceled 是否被取消

func (*UnexportedFuncMocker) Origin

func (m *UnexportedFuncMocker) Origin(originFunc interface{}) UnExportedMocker

Origin 调用原函数

func (*UnexportedFuncMocker) String

func (m *UnexportedFuncMocker) String() string

String mock 的名称或描述, 方便调试和问题排查

type UnexportedMethodMocker

type UnexportedMethodMocker struct {
	// contains filtered or unexported fields
}

UnexportedMethodMocker 对结构体函数或方法进行 mock 能支持到未导出类型、未导出类型的方法的 Mock

func NewUnexportedMethodMocker

func NewUnexportedMethodMocker(pkgName string, structName string) *UnexportedMethodMocker

NewUnexportedMethodMocker 创建未导出方法 Mocker pkgName 包路径 structName 结构体名称

func (*UnexportedMethodMocker) Apply

func (m *UnexportedMethodMocker) Apply(callback interface{})

Apply 指定 mock 执行的回调函数 mock 回调函数, 需要和 mock 模板函数的签名保持一致 方法的参数签名写法比如: func(s *Struct, arg1, arg2 type), 其中第一个参数必须是接收体类型

func (*UnexportedMethodMocker) As

func (m *UnexportedMethodMocker) As(aFunc interface{}) ExportedMocker

As 将未导出函数(或方法)转换为导出函数(或方法)

func (UnexportedMethodMocker) Cancel

func (m UnexportedMethodMocker) Cancel()

Cancel 取消 Mock

func (UnexportedMethodMocker) Canceled

func (m UnexportedMethodMocker) Canceled() bool

Canceled 是否被取消

func (*UnexportedMethodMocker) Method

Method 设置结构体的方法名

func (*UnexportedMethodMocker) Origin

func (m *UnexportedMethodMocker) Origin(originFunc interface{}) UnExportedMocker

Origin 调用原函数

func (*UnexportedMethodMocker) String

func (m *UnexportedMethodMocker) String() string

String mock 的名称或描述, 方便调试和问题排查

type VarMock

type VarMock interface {
	Mocker
	// Set 设置变量值, val 类型必须和变量指针指向的值的类型一致
	Set(val interface{})
}

VarMock 变量 mock 支持全局变量, 任意类型包括不限于基本类型,结构体,函数变量,指针与非指针类型 主要提供方便变量 mock/reset 场景的能力支持

func NewVarMocker

func NewVarMocker(target interface{}) VarMock

NewVarMocker 创建 VarMock

type When

type When struct {
	ExportedMocker
	// contains filtered or unexported fields
}

When Mock 条件匹配。 当参数等于指定的值时,会 return 对应的指定值

func CreateWhen

func CreateWhen(m ExportedMocker, funcDef interface{}, args []interface{},
	defaultReturns []interface{}, isMethod bool) (*When, error)

CreateWhen 构造条件判断 param 参数条件 defaultReturns 默认返回值 isMethod 是否为方法类型

func NewWhen

func NewWhen(funTyp reflect.Type) *When

NewWhen 创建默认 When

func (*When) AndReturn

func (w *When) AndReturn(value ...interface{}) *When

AndReturn 指定第二次调用返回值,之后的调用以最后一个指定的值返回

func (*When) Eval

func (w *When) Eval(args ...interface{}) []interface{}

Eval 执行 when 子句

func (*When) In

func (w *When) In(specArgsOrExprs ...interface{}) *When

In 当参数包含其中之一, 使用 ContainsMatcher 当参数为多个时, In 的每个条件各使用一个数组表示: .In([]interface{}{3, Any()}, []interface{}{4, Any()})

func (*When) Matches

func (w *When) Matches(argAndRet ...arg.Pair) *When

Matches 多个条件匹配

func (*When) Return

func (w *When) Return(value ...interface{}) *When

Return 指定返回值

func (*When) Returns

func (w *When) Returns(values ...interface{}) *When

Returns 按顺序依次返回值

func (*When) When

func (w *When) When(specArgOrExpr ...interface{}) *When

When 当参数符合一定的条件, 使用 DefaultMatcher 入参个数必须和函数或方法参数个数一致, 比如: When(

In(3, 4), // 第一个参数是 In
Any()) // 第二个参数是 Any

Directories

Path Synopsis
Package arg 负责参数表达式构造和执行, 执行结果用于 When 参数匹配(Matcher)
Package arg 负责参数表达式构造和执行, 执行结果用于 When 参数匹配(Matcher)
Package erro 收拢了所有的错误类型,错误溯源类型等 1.
Package erro 收拢了所有的错误类型,错误溯源类型等 1.
internal
arch/x86asm
Package x86asm implements decoding of x86 machine code.
Package x86asm implements decoding of x86 machine code.
bytecode
Package bytecode 是内存字节码层面操作的工具集
Package bytecode 是内存字节码层面操作的工具集
bytecode/memory
Package memory 包负责内存读写控制
Package memory 包负责内存读写控制
bytecode/stub
Package stub 负责管理桩函数内存管理
Package stub 负责管理桩函数内存管理
hack
Package hack 对 go 系统包的 hack, 包含一些系统结构体的 copy,需要和每个 go 版本保持同步
Package hack 对 go 系统包的 hack, 包含一些系统结构体的 copy,需要和每个 go 版本保持同步
iface
Package iface 生成 interface 的实例对象, 通过 fake iface 结果获得
Package iface 生成 interface 的实例对象, 通过 fake iface 结果获得
logger
Package logger 负责日志收敛,给日志添加前缀和独立文件输出,以便在本框架被集成之后的日志可读
Package logger 负责日志收敛,给日志添加前缀和独立文件输出,以便在本框架被集成之后的日志可读
proxy
Package proxy 封装了给各种类型的代理(或较 patch)中间层 负责比如外部传如类型校验、私有函数名转换成 uintptr、trampoline 初始化、并发 proxy 等
Package proxy 封装了给各种类型的代理(或较 patch)中间层 负责比如外部传如类型校验、私有函数名转换成 uintptr、trampoline 初始化、并发 proxy 等
unexports
Package unexports 实现了对未导出函数的获取 基于 github.com/alangpierce/go-forceexport 进行了修改和扩展。
Package unexports 实现了对未导出函数的获取 基于 github.com/alangpierce/go-forceexport 进行了修改和扩展。
Package test 兼容性测试、跨包结构测试工具类
Package test 兼容性测试、跨包结构测试工具类

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL