面试题答案
一键面试Go语言中实现Mock的常用方式
- 手动编写Mock代码:通过创建一个实现了目标接口的结构体,并在结构体方法中编写模拟逻辑。这种方式灵活,但对于复杂接口编写工作量大。
- 使用工具自动生成Mock代码:如
gomock
。它基于Go的interface
生成Mock代码,减少手动编写工作量,提高代码一致性。
以数据库查询接口为例使用Mock进行测试
假设我们有一个简单的数据库查询接口:
// DatabaseQueryer 数据库查询接口
type DatabaseQueryer interface {
QueryRow(query string, args ...interface{}) (string, error)
}
手动编写Mock代码进行测试
package main
import (
"fmt"
"testing"
)
// MockDatabaseQueryer 手动编写的Mock结构体
type MockDatabaseQueryer struct{}
// QueryRow Mock实现
func (m MockDatabaseQueryer) QueryRow(query string, args ...interface{}) (string, error) {
// 这里简单返回固定值,实际可根据逻辑调整
return "mocked result", nil
}
func TestDatabaseQuery(t *testing.T) {
mockDB := MockDatabaseQueryer{}
result, err := mockDB.QueryRow("SELECT * FROM users WHERE id =?", 1)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if result != "mocked result" {
t.Errorf("Expected'mocked result', got '%s'", result)
}
}
使用gomock
生成Mock代码进行测试
- 安装
gomock
:
go install github.com/golang/mock/mockgen@latest
- 生成Mock代码:
假设我们的接口定义在
main.go
文件中,执行以下命令生成Mock代码:
mockgen -destination mock_database.go -package main main DatabaseQueryer
这会在mock_database.go
文件中生成MockDatabaseQueryer
结构体及其方法。
3. 使用生成的Mock代码进行测试:
package main
import (
"fmt"
"testing"
"github.com/golang/mock/gomock"
)
func TestDatabaseQueryWithGomock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockDB := NewMockDatabaseQueryer(ctrl)
mockDB.EXPECT().QueryRow("SELECT * FROM users WHERE id =?", 1).Return("mocked result", nil)
result, err := mockDB.QueryRow("SELECT * FROM users WHERE id =?", 1)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if result != "mocked result" {
t.Errorf("Expected'mocked result', got '%s'", result)
}
}