github.com/bytedance/mockey@v1.2.10/internal/monkey/patch_test.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package monkey 18 19 import ( 20 "reflect" 21 "testing" 22 23 "github.com/smartystreets/goconvey/convey" 24 ) 25 26 //go:noinline 27 func Target() int { 28 return 0 29 } 30 31 func Hook() int { 32 return 2 33 } 34 35 func UnsafeTarget() {} 36 37 func TestPatchFunc(t *testing.T) { 38 convey.Convey("TestPatchFunc", t, func() { 39 convey.Convey("normal", func() { 40 var proxy func() int 41 patch := PatchFunc(Target, Hook, &proxy, false) 42 convey.So(Target(), convey.ShouldEqual, 2) 43 convey.So(proxy(), convey.ShouldEqual, 0) 44 patch.Unpatch() 45 convey.So(Target(), convey.ShouldEqual, 0) 46 }) 47 convey.Convey("anonymous hook", func() { 48 var proxy func() int 49 patch := PatchFunc(Target, func() int { return 2 }, &proxy, false) 50 convey.So(Target(), convey.ShouldEqual, 2) 51 convey.So(proxy(), convey.ShouldEqual, 0) 52 patch.Unpatch() 53 convey.So(Target(), convey.ShouldEqual, 0) 54 }) 55 convey.Convey("closure hook", func() { 56 var proxy func() int 57 hookBuilder := func(x int) func() int { 58 return func() int { return x } 59 } 60 patch := PatchFunc(Target, hookBuilder(2), &proxy, false) 61 convey.So(Target(), convey.ShouldEqual, 2) 62 convey.So(proxy(), convey.ShouldEqual, 0) 63 patch.Unpatch() 64 convey.So(Target(), convey.ShouldEqual, 0) 65 }) 66 convey.Convey("reflect hook", func() { 67 var proxy func() int 68 hookVal := reflect.MakeFunc(reflect.TypeOf(Hook), func(args []reflect.Value) (results []reflect.Value) { return []reflect.Value{reflect.ValueOf(2)} }) 69 patch := PatchFunc(Target, hookVal.Interface(), &proxy, false) 70 convey.So(Target(), convey.ShouldEqual, 2) 71 convey.So(proxy(), convey.ShouldEqual, 0) 72 patch.Unpatch() 73 convey.So(Target(), convey.ShouldEqual, 0) 74 }) 75 convey.Convey("unsafe", func() { 76 var proxy func() 77 patch := PatchFunc(UnsafeTarget, func() { panic("good") }, &proxy, true) 78 convey.So(func() { UnsafeTarget() }, convey.ShouldPanicWith, "good") 79 convey.So(func() { proxy() }, convey.ShouldNotPanic) 80 patch.Unpatch() 81 convey.So(func() { UnsafeTarget() }, convey.ShouldNotPanic) 82 }) 83 }) 84 }