github.com/gbl08ma/monkey@v1.1.0/monkey_test.go (about) 1 package monkey_test 2 3 import ( 4 "reflect" 5 "runtime" 6 "testing" 7 "time" 8 9 "github.com/gbl08ma/monkey" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 //go:noinline 14 func no() bool { return false } 15 16 //go:noinline 17 func yes() bool { return true } 18 19 func TestTimePatch(t *testing.T) { 20 before := time.Now() 21 monkey.Patch(time.Now, func() time.Time { 22 return time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) 23 }) 24 during := time.Now() 25 assert.True(t, monkey.Unpatch(time.Now)) 26 after := time.Now() 27 28 assert.Equal(t, time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), during) 29 assert.NotEqual(t, before, during) 30 assert.NotEqual(t, during, after) 31 } 32 33 func TestGC(t *testing.T) { 34 value := true 35 monkey.Patch(no, func() bool { 36 return value 37 }) 38 defer monkey.UnpatchAll() 39 runtime.GC() 40 assert.True(t, no()) 41 } 42 43 func TestSimple(t *testing.T) { 44 assert.False(t, no()) 45 monkey.Patch(no, yes) 46 assert.True(t, no()) 47 assert.True(t, monkey.Unpatch(no)) 48 assert.False(t, no()) 49 assert.False(t, monkey.Unpatch(no)) 50 } 51 52 func TestGuard(t *testing.T) { 53 var guard *monkey.PatchGuard 54 guard = monkey.Patch(no, func() bool { 55 guard.Unpatch() 56 defer guard.Restore() 57 return !no() 58 }) 59 for i := 0; i < 100; i++ { 60 assert.True(t, no()) 61 } 62 monkey.Unpatch(no) 63 } 64 65 func TestUnpatchAll(t *testing.T) { 66 assert.False(t, no()) 67 monkey.Patch(no, yes) 68 assert.True(t, no()) 69 monkey.UnpatchAll() 70 assert.False(t, no()) 71 } 72 73 type s struct{} 74 75 func (s *s) yes() bool { return true } 76 77 func TestWithInstanceMethod(t *testing.T) { 78 i := &s{} 79 80 assert.False(t, no()) 81 monkey.Patch(no, i.yes) 82 assert.True(t, no()) 83 monkey.Unpatch(no) 84 assert.False(t, no()) 85 } 86 87 type f struct{} 88 89 //go:noinline 90 func (f *f) No() bool { return false } 91 92 func TestOnInstanceMethod(t *testing.T) { 93 i := &f{} 94 assert.False(t, i.No()) 95 monkey.PatchInstanceMethod(reflect.TypeOf(i), "No", func(_ *f) bool { return true }) 96 assert.True(t, i.No()) 97 assert.True(t, monkey.UnpatchInstanceMethod(reflect.TypeOf(i), "No")) 98 assert.False(t, i.No()) 99 } 100 101 func TestNotFunction(t *testing.T) { 102 assert.Panics(t, func() { 103 monkey.Patch(no, 1) 104 }) 105 assert.Panics(t, func() { 106 monkey.Patch(1, yes) 107 }) 108 } 109 110 func TestNotCompatible(t *testing.T) { 111 assert.Panics(t, func() { 112 monkey.Patch(no, func() {}) 113 }) 114 }