github.com/bytedance/mockey@v1.2.10/convey.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 mockey 18 19 import ( 20 "reflect" 21 22 "github.com/bytedance/mockey/internal/tool" 23 "github.com/smartystreets/goconvey/convey" 24 ) 25 26 var gMocker = make([]map[uintptr]mockerInstance, 0) 27 28 func init() { 29 gMocker = append(gMocker, make(map[uintptr]mockerInstance)) 30 } 31 32 func PatchConvey(items ...interface{}) { 33 for i, item := range items { 34 if reflect.TypeOf(item).Kind() == reflect.Func { 35 items[i] = reflect.MakeFunc(reflect.TypeOf(item), func(args []reflect.Value) []reflect.Value { 36 gMocker = append(gMocker, make(map[uintptr]mockerInstance)) 37 defer func() { 38 for _, mocker := range gMocker[len(gMocker)-1] { 39 mocker.unPatch() 40 } 41 gMocker = gMocker[:len(gMocker)-1] 42 }() 43 return tool.ReflectCall(reflect.ValueOf(item), args) 44 }).Interface() 45 } 46 } 47 48 convey.Convey(items...) 49 } 50 51 func addToGlobal(mocker mockerInstance) { 52 tool.DebugPrintf("%v added\n", mocker.key()) 53 last, ok := gMocker[len(gMocker)-1][mocker.key()] 54 if ok { 55 tool.Assert(!ok, "re-mock %v, previous mock at: %v", mocker.name(), last.caller()) 56 } 57 gMocker[len(gMocker)-1][mocker.key()] = mocker 58 } 59 60 func removeFromGlobal(mocker mockerInstance) { 61 tool.DebugPrintf("%v removed\n", mocker.key()) 62 delete(gMocker[len(gMocker)-1], mocker.key()) 63 } 64 65 // Unpatch all mocks in current 'PatchConvey' context 66 // 67 // If the caller is out of 'PatchConvey', it will unpatch all mocks 68 // 69 // For example: 70 // 71 // Test1(t) { 72 // Mock(a).Build() 73 // Mock(b).Build() 74 // 75 // // a and b will be unpatched 76 // UnpatchAll() 77 // } 78 // }) 79 // 80 // Test2(t) { 81 // Mock(a).Build() 82 // PatchConvey(t,func(){ 83 // Mock(b).Build() 84 // 85 // // only b will be unpatched 86 // UnpatchAll() 87 // } 88 // }) 89 func UnPatchAll() { 90 for _, mocker := range gMocker[len(gMocker)-1] { 91 mocker.unPatch() 92 } 93 }