monkey

package module
v0.0.0-...-1e77428 Latest Latest
Warning

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

Go to latest
Published: Nov 14, 2022 License: MIT Imports: 8 Imported by: 0

README

Go语言猴子补丁框架 🙉 🐒

test workflow

Go 语言猴子补丁(monkey patching)框架。

本项目对 Bouke 的项目做了优化,不同协程可以独立 patch 同一个函数而互不影响。从而可以并发运行单元测试。

工作原理请参考我的系列文章:

Bouke 已经不再维护原项目,所以只能开一个新项目了🤣。

有兴趣的同学也可以加微信 taoshu-in 讨论,拉你进群。

快速入门

首先,引入 monkey 包

go getgithub.com/evlic/monkey

然后,调用 monkey.Patch 方法 mock 指定函数。

package main

import (
	"fmt"

	"github.com/go-kiss/monkey"
)

func sum(a, b int) int { return a + b }

func sub1[T int|float64](a, b T) T { return a - b }
func sub2[T int|float64](a, b T) T { return a + b }

type S struct { i int }

func (s *S) Get() int { return i }

func main() {
	// mock 普通函数
	monkey.Patch(sum, func(a b int) int { return a - b })
	fmt.Println(sum(1, 2)) // 输出 -1
	// mock 泛型函数
	monkey.Patch(sub1[int], sub2[int])
	fmt.Println(sub1(1, 2)) // 输出 3
	// mock 结构体方法
	monkey.Patch((*s).Get, func(s *S) int { return -1 })
	var s S
	fmt.Println(s.Get()) // 输出 -1
}

更多用法请参考使用示例测试用例

注意事项

  1. Monkey 需要关闭 Go 语言的内联优化才能生效,比如测试的时候需要:go test -gcflags=all=-l
  2. Monkey 需要在运行的时候修改内存代码段,因而无法在一些对安全性要求比较高的系统上工作。
  3. Monkey 不应该用于生产系统,但用来 mock 测试代码还是没有问题的。
  4. Monkey 目前仅支持 amd64 指令架构,支持 linux/macos/windows 平台。

Documentation

Index

Constants

This section is empty.

Variables

View Source
var OptGeneric = optGeneric{}
View Source
var OptGlobal = optGlobal{}

Functions

func PatchEmpty

func PatchEmpty(target interface{})

PatchEmpty patches target with empty patch. Call the target will run the original func.

func Unpatch

func Unpatch(target interface{}) bool

Unpatch removes any monkey patches on target returns whether target was patched in the first place

func UnpatchAll

func UnpatchAll()

UnpatchAll removes all applied monkeypatches

func UnpatchInstanceMethod

func UnpatchInstanceMethod(target reflect.Type, methodName string) bool

UnpatchInstanceMethod removes the patch on methodName of the target returns whether it was patched in the first place

Types

type Option

type Option interface {
	// contains filtered or unexported methods
}

type PatchGuard

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

func Patch

func Patch(target, replacement interface{}, opts ...Option) *PatchGuard

Patch replaces a function with another for current goroutine only.

Usage examples:

Patch(math.Abs, func(n float64) { return 0 })
Patch((*net.Dialer).Dial, func(_ *net.Dialer, _, _ string) (net.Conn, error) {})

func (*PatchGuard) Restore

func (g *PatchGuard) Restore()

func (*PatchGuard) Unpatch

func (g *PatchGuard) Unpatch()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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