github.com/tencent/goom@v1.0.1/when_test.go (about) 1 // Package mocker_test 对 mocker 包的测试 2 // 当前文件实现了对 when.go 的单测 3 package mocker_test 4 5 import ( 6 "reflect" 7 "testing" 8 9 "github.com/stretchr/testify/suite" 10 mocker "github.com/tencent/goom" 11 "github.com/tencent/goom/arg" 12 ) 13 14 // TestUnitWhenTestSuite 测试入口 15 func TestUnitWhenTestSuite(t *testing.T) { 16 suite.Run(t, new(WhenTestSuite)) 17 } 18 19 // mockerTestSuite Builder 测试套件 20 type WhenTestSuite struct { 21 suite.Suite 22 } 23 24 // simple 普通函数 25 func simple(int) int { 26 return 0 27 } 28 29 // Arg 普通参数 30 type Arg struct { 31 field1 string 32 } 33 34 // Result 普通返回结果 35 type Result struct { 36 field1 int 37 } 38 39 // complex 复杂返回结果函数 40 func complex(Arg) Result { 41 return Result{0} 42 } 43 44 // complex1 复杂带指针的返回结果函数 45 func complex1(Arg) *Result { 46 return &Result{0} 47 } 48 49 // Struct for 结构体方法 When 50 type Struct struct{} 51 52 // Div 除法操作 53 // 54 //go:noinline 55 func (s *Struct) Div(a int, b int) int { 56 return a / b 57 } 58 59 // Expand 展开数组 60 // 61 //go:noinline 62 func (s *Struct) Expand(arg []int) (int, int) { 63 if len(arg) != 2 { 64 return 0, 0 65 } 66 return arg[0], arg[1] 67 } 68 69 // StructOuter 嵌套结构外层 70 type StructOuter struct { 71 } 72 73 // Compute 中会调用 sub 运算 74 func (s *StructOuter) Compute(a int, b int) int { 75 diver := new(Struct) 76 res := diver.Div(a, b) 77 78 return res 79 } 80 81 // TestWhen 测试简单参数匹配 82 func (s *WhenTestSuite) TestWhen() { 83 s.Run("success", func() { 84 when := mocker.NewWhen(reflect.TypeOf(simple)) 85 when.When(1).Return(2) 86 87 s.Equal(2, when.Eval(1)[0], "when result check") 88 }) 89 } 90 91 // TestWhenAndReturn 多次返回不同的值 92 func (s *WhenTestSuite) TestWhenAndReturn() { 93 s.Run("success", func() { 94 when := mocker.NewWhen(reflect.TypeOf(simple)) 95 when.When(1).Return(2).AndReturn(3) 96 97 s.Equal(2, when.Eval(1)[0], "when result check") 98 s.Equal(3, when.Eval(1)[0], "when result check") 99 s.Equal(3, when.Eval(1)[0], "when result check") 100 }) 101 } 102 103 // TestReturns 依次返回不同的值 104 func (s *WhenTestSuite) TestReturns() { 105 s.Run("success", func() { 106 when := mocker.NewWhen(reflect.TypeOf(simple)) 107 when.Returns(1, 2, 3) 108 109 s.Equal(1, when.Eval(1)[0], "when result check") 110 s.Equal(2, when.Eval(1)[0], "when result check") 111 s.Equal(3, when.Eval(1)[0], "when result check") 112 113 when.When(2).Returns(4, 5, 6) 114 115 s.Equal(4, when.Eval(2)[0], "when result check") 116 s.Equal(5, when.Eval(2)[0], "when result check") 117 s.Equal(6, when.Eval(2)[0], "when result check") 118 119 // 多参 Returns 120 struct1 := new(Struct) 121 m := mocker.Create() 122 m.Struct(struct1).Method("Expand").Returns( 123 []interface{}{1, 1}, []interface{}{2, 2}, []interface{}{3, 3}) 124 125 ret1, ret2 := struct1.Expand([]int{0, 0}) 126 s.Equal(1, ret1, "method when check") 127 s.Equal(1, ret2, "method when check") 128 129 ret1, ret2 = struct1.Expand([]int{0, 0}) 130 s.Equal(2, ret1, "method when check") 131 s.Equal(2, ret2, "method when check") 132 133 ret1, ret2 = struct1.Expand([]int{0, 0}) 134 s.Equal(3, ret1, "method when check") 135 s.Equal(3, ret2, "method when check") 136 137 // 复杂返回结构 138 when = mocker.NewWhen(reflect.TypeOf(complex1)) 139 when.Returns(&Result{}, nil) 140 s.Equal(&Result{}, when.Eval(Arg{})[0], "when result check") 141 s.Equal(nil, when.Eval(Arg{})[0], "when result check") 142 }) 143 } 144 145 // TestWhenContains 任意一个配 146 func (s *WhenTestSuite) TestWhenContains() { 147 s.Run("success", func() { 148 when := mocker.NewWhen(reflect.TypeOf(simple)) 149 when.Return(-1).In(1, 2).Return(5) 150 151 s.Equal(5, when.Eval(1)[0], "when result check") 152 s.Equal(5, when.Eval(1)[0], "when result check") 153 s.Equal(-1, when.Eval(0)[0], "when result check") 154 155 when.Return(-1).When(arg.In(3, 4)).Return(6) 156 157 s.Equal(6, when.Eval(3)[0], "when result check") 158 s.Equal(6, when.Eval(4)[0], "when result check") 159 }) 160 } 161 162 // TestMatches 测试批量设置条件 163 func (s *WhenTestSuite) TestMatches() { 164 s.Run("success", func() { 165 when := mocker.NewWhen(reflect.TypeOf(simple)) 166 when.Return(-1).Matches( 167 arg.Pair{Args: 1, Return: 5}, 168 arg.Pair{Args: 2, Return: 5}, 169 arg.Pair{Args: 3, Return: 6}) 170 171 s.Equal(5, when.Eval(1)[0], "when result check") 172 s.Equal(5, when.Eval(2)[0], "when result check") 173 s.Equal(6, when.Eval(3)[0], "when result check") 174 175 when.Matches(arg.Pair{Args: arg.Any(), Return: 100}) 176 s.Equal(100, when.Eval(4)[0], "when result check") 177 }) 178 } 179 180 // TestNil 测试复杂参数 181 func (s *WhenTestSuite) TestComplex() { 182 s.Run("success", func() { 183 when := mocker.NewWhen(reflect.TypeOf(complex)) 184 when.Return(Result{}).When(Arg{field1: "ok"}).Return(Result{0}). 185 When(Arg{field1: "not ok"}).Return(Result{-1}) 186 187 s.Equal(Result{0}, when.Eval(Arg{field1: "ok"})[0], "when result check") 188 s.Equal(Result{-1}, when.Eval(Arg{field1: "not ok"})[0], "when result check") 189 s.Equal(Result{}, when.Eval(Arg{field1: "other"})[0], "when result check") 190 }) 191 } 192 193 // TestNil 测试空参数 194 func (s *WhenTestSuite) TestNil() { 195 s.Run("success", func() { 196 when := mocker.NewWhen(reflect.TypeOf(complex1)) 197 when.Return(nil) 198 199 s.Equal(nil, when.Eval(Arg{})[0], "when return nil check") 200 }) 201 } 202 203 // TestMethodWhen 方法参数条件匹配 204 func (s *WhenTestSuite) TestMethodWhen() { 205 s.Run("success", func() { 206 structOuter := new(StructOuter) 207 struct1 := new(Struct) 208 m := mocker.Create() 209 210 // 直接 mock 方法的返回值 211 m.Struct(struct1).Method("Div").Return(100) 212 s.Equal(100, structOuter.Compute(2, 1), "method when check") 213 214 m.Reset() 215 m.Struct(struct1).Method("Div").Return(50) 216 s.Equal(50, structOuter.Compute(2, 1), "method when check") 217 218 m.Struct(struct1).Method("Div").When(3, 4).Return(100) 219 m.Struct(struct1).Method("Div").When(4, 4).Return(200) 220 s.Equal(100, structOuter.Compute(3, 4), "method when check") 221 s.Equal(200, structOuter.Compute(4, 4), "method when check") 222 223 // mock 方法的替换方法 224 m.Struct(struct1).Method("Div").Apply(func(_ *Struct, a int, b int) int { 225 return a/b + 1 226 }) 227 s.Equal(3, structOuter.Compute(2, 1), "method when check") 228 }) 229 } 230 231 // TestMethodAny 方法参数 Any 条件匹配 232 func (s *WhenTestSuite) TestMethodAny() { 233 s.Run("success", func() { 234 structOuter := new(StructOuter) 235 struct1 := new(Struct) 236 m := mocker.Create() 237 238 m.Struct(struct1).Method("Div").When(3, arg.Any()).Return(100) 239 s.Equal(100, structOuter.Compute(3, 1), "method when check") 240 s.Equal(100, structOuter.Compute(3, 2), "method when check") 241 s.Equal(100, structOuter.Compute(3, -1), "method when check") 242 }) 243 } 244 245 // TestMethodMultiIn 方法参数 Any 条件匹配 246 func (s *WhenTestSuite) TestMethodMultiIn() { 247 s.Run("success", func() { 248 structOuter := new(StructOuter) 249 struct1 := new(Struct) 250 m := mocker.Create() 251 252 when := m.Struct(struct1).Method("Div").Return(-1).When(arg.In(3, 4), arg.Any()).Return(100) 253 s.Equal(100, structOuter.Compute(3, 1), "method when check") 254 s.Equal(100, structOuter.Compute(3, 2), "method when check") 255 s.Equal(100, structOuter.Compute(4, 3), "method when check") 256 s.Equal(100, structOuter.Compute(3, -1), "method when check") 257 258 when.In([]interface{}{5, arg.Any()}).Return(101) 259 s.Equal(101, structOuter.Compute(5, 1), "method when check") 260 s.Equal(101, structOuter.Compute(5, 2), "method when check") 261 s.Equal(101, structOuter.Compute(5, -1), "method when check") 262 263 when.Matches( 264 arg.Pair{Args: []interface{}{6, arg.Any()}, Return: []interface{}{101}}, 265 arg.Pair{Args: []interface{}{7, arg.Any()}, Return: []interface{}{102}}, 266 ) 267 s.Equal(101, structOuter.Compute(6, -1), "method when check") 268 s.Equal(102, structOuter.Compute(7, -1), "method when check") 269 }) 270 }