应该可以为需要使用从第 3 方库导入的结构中的方法编写自己的接口。
type MongoClient interface {
FindOne(context.Context, mongo.D) (*mongo.SingleResult, error)
}
type myClientBeingTested struct {
client MongoClient
}
// in tests
type mockMongoClient struct {
// implement MongoClient, pass in to myClientBeingTested
}
但是,对于大多数应用程序,它提供了更好的保证,可以针对本地或内存数据库运行测试,以验证一切是否端到端工作。如果这变得太慢,那么在业务逻辑级别而不是数据库查询级别进行模拟是有意义的。
例如:
type User struct {}
type UserMgmt interface {
Login(email, pass string) (*User, error)
}
// for testing api or workflows
type MockUserMgmt struct {}
// for production app
type LiveUserMgmt struct {
client *mongo.Client
}
在单元测试中它看起来像:
// user_mgmt_test.go test code
userMgmt := &LiveUserMgmt{client: mongo.Connect("localhost")}
// test public library methods
在 api 或工作流测试中,它看起来像:
userMgmt := &MockUserMgmt{}
// example pass to api routes
api := &RequestHandler{
UserMgmt: userMgmt,
}
// The mongo struct you depend on and need to mock
type mongo struct {
someState string
}
// The real world function you need to mock out
func (m *mongo) Foo() error {
// do stuff
return nil
}
// Construct an interface with a method that matches the signature you need to mock
type mockableMongoInterface interface {
Foo() error
}
现在依赖于 mockableMongoInterface 而不是直接依赖于 mongo。您仍然可以将您的第三方 mongo 结构传递给您需要它的站点,因为 go 将通过接口了解类型。
这与 Adrian 对您的问题的评论一致。