Golang中使用Go Mock模拟接口的实践指南

Golang中使用Go Mock模拟接口的实践指南 我正在使用 gomock 版本 1.6.0。以下是我的使用方式。

//go:generate mockgen -destination=./mytype_mock_test.go -package=mytype_test -build_flags=-mod=mod {{module name}}/{{path_to_my_type_intertface}} MyType
type MyType interface {
	Ge(ctx context.Context, id int64) (*Type, error)
	Updater(ctx context.Context, type *Type) error
	Create(ctx context.Context, type *Type) error
}

这是我用于生成模拟对象的脚本。

#!/bin/bash

go install github.com/golang/mock/mockgen@v1.6.0

go generate ./...

模拟对象已成功生成,但当我运行测试时(我使用 Bazel 在微服务单体仓库中运行它们),遇到了以下错误。

{{path_to_my_type_intertface}}/rmytype_mock_test.go:40:9: m.ctrl.T undefined (type *gomock.Controller has no field or method T)
43
{{path_to_my_type_intertface}}/mytype_mock_test.go:48:15: mr.mock.ctrl.T undefined (type *gomock.Controller has no field or method T)

你知道这可能是什么原因吗?因为我看到 gomock.Controller 类型中确实有 T 字段。

谢谢!


更多关于Golang中使用Go Mock模拟接口的实践指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用Go Mock模拟接口的实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这个错误通常是由于 gomock 版本不匹配导致的。gomock 1.6.0 中的 Controller 结构体确实有 T 字段,但你可能在测试中使用了不同版本的 gomock 包。

检查你的 go.mod 文件中 gomock 的实际版本:

// go.mod 示例
module your-module

go 1.21

require (
    github.com/golang/mock v1.6.0
)

确保测试运行时使用的是相同版本。在 Bazel 环境中,需要检查 BUILD.bazel 文件中的依赖声明:

# BUILD.bazel 示例
go_test(
    name = "mytype_test",
    srcs = ["mytype_test.go"],
    deps = [
        "//path/to/your:gomock",
        "@com_github_golang_mock//:mockgen",
    ],
)

如果版本正确,问题可能在于生成的 mock 文件引用了错误的导入路径。检查生成的 mock 文件头部:

// mytype_mock_test.go
// Code generated by MockGen. DO NOT EDIT.

package mytype_test

import (
    gomock "github.com/golang/mock/gomock"
    reflect "reflect"
)

临时解决方案是重新生成 mock 文件并清理缓存:

# 清理生成的 mock 文件
rm -f mytype_mock_test.go

# 重新生成
go generate ./...

# 清理 Go 模块缓存
go clean -modcache

# 或者针对 Bazel
bazel clean --expunge

如果问题仍然存在,尝试显式指定 gomock 的导入路径:

go:generate mockgen -destination=./mytype_mock_test.go -package=mytype_test -build_flags=-mod=mod gomock=github.com/golang/mock/gomock {{module name}}/{{path_to_my_type_intertface}} MyType

检查你的测试文件是否正确地设置了 Controller:

// 正确的测试示例
func TestMyType(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()
    
    mockMyType := NewMockMyType(ctrl)
    // 测试逻辑...
}

版本冲突是最可能的原因。确保所有地方都使用相同的 gomock 版本:

# 检查实际使用的版本
go list -m all | grep gomock

# 强制使用特定版本
go get github.com/golang/mock@v1.6.0
go mod tidy
回到顶部