package handler_test // TODO 使用 mock测试 handler // 一、安装 GoMock // 首先需要安装 GoMock 和 mockgen 工具: // bash // 复制 // # 安装 GoMock 包 // go get github.com/golang/mock/gomock // # 安装 mockgen 工具 // go install github.com/golang/mock/mockgen@latest // 二、基本使用步骤 // 1. 定义接口 // 假设我们有一个简单的接口: // go // 复制 // // greeter.go // package main // type Greeter interface { // Greet(name string) string // } // 2. 生成 mock 代码 // 使用 mockgen 为接口生成 mock 实现: // bash // 复制 // mockgen -source=greeter.go -destination=mock_greeter.go -package=main // 这会生成一个 mock_greeter.go 文件,包含 MockGreeter 结构体。 // 3. 编写测试代码 // go // 复制 // // greeter_test.go // package main // import ( // "testing" // "github.com/golang/mock/gomock" // ) // func TestGreet(t *testing.T) { // // 创建控制器 // ctrl := gomock.NewController(t) // defer ctrl.Finish() // 断言所有期望都被满足 // // 创建 mock 对象 // mockGreeter := NewMockGreeter(ctrl) // // 设置期望 // mockGreeter.EXPECT(). // Greet("Alice"). // Return("Hello, Alice!"). // Times(1) // // 使用 mock 对象 // result := mockGreeter.Greet("Alice") // // 验证结果 // if result != "Hello, Alice!" { // t.Errorf("Expected 'Hello, Alice!', got '%s'", result) // } // } // 三、高级功能 // 1. 参数匹配 // GoMock 提供了多种参数匹配方式: // go // 复制 // // 精确匹配 // mockGreeter.EXPECT().Greet("Alice") // // 任意值匹配 // mockGreeter.EXPECT().Greet(gomock.Any()) // // 自定义匹配 // mockGreeter.EXPECT().Greet(gomock.AssignableToTypeOf("")).DoAndReturn( // func(name string) string { // return "Hello, " + name + "!" // }, // ) // 2. 调用次数控制 // go // 复制 // // 精确调用次数 // mockGreeter.EXPECT().Greet("Alice").Times(3) // // 至少调用一次 // mockGreeter.EXPECT().Greet("Alice").MinTimes(1) // // 最多调用一次 // mockGreeter.EXPECT().Greet("Alice").MaxTimes(1) // // 任意次数(0或多次) // mockGreeter.EXPECT().Greet("Alice").AnyTimes() // 3. 调用顺序控制 // go // 复制 // gomock.InOrder( // mockGreeter.EXPECT().Greet("Alice"), // mockGreeter.EXPECT().Greet("Bob"), // ) // 4. 模拟副作用 // go // 复制 // // 使用 Do // mockGreeter.EXPECT().Greet("Alice").Do(func(name string) { // t.Logf("Greet was called with %s", name) // }) // // 使用 DoAndReturn // mockGreeter.EXPECT().Greet("Alice").DoAndReturn( // func(name string) string { // return "Hi, " + name + "!" // }, // ) // 四、实际应用示例 // 假设我们有一个服务依赖 Greeter 接口: // go // 复制 // // greeter_service.go // package main // type GreeterService struct { // greeter Greeter // } // func (s *GreeterService) WelcomePeople(names []string) []string { // var greetings []string // for _, name := range names { // greetings = append(greetings, s.greeter.Greet(name)) // } // return greetings // } // 对应的测试: // go // 复制 // // greeter_service_test.go // package main // import ( // "testing" // "github.com/golang/mock/gomock" // ) // func TestWelcomePeople(t *testing.T) { // ctrl := gomock.NewController(t) // defer ctrl.Finish() // mockGreeter := NewMockGreeter(ctrl) // service := &GreeterService{greeter: mockGreeter} // // 设置期望 // mockGreeter.EXPECT().Greet("Alice").Return("Hello, Alice!") // mockGreeter.EXPECT().Greet("Bob").Return("Hello, Bob!") // // 测试 // result := service.WelcomePeople([]string{"Alice", "Bob"}) // // 验证 // expected := []string{"Hello, Alice!", "Hello, Bob!"} // if len(result) != len(expected) { // t.Fatalf("Expected %d greetings, got %d", len(expected), len(result)) // } // for i := range expected { // if result[i] != expected[i] { // t.Errorf("At index %d: expected %q, got %q", i, expected[i], result[i]) // } // } // }