使用结构体作为接口而不实现所有方法

Ale*_*drT 8 methods unit-testing interface go

例如我有 20 个方法的 dao。

type UserDao interface {
    GetUser() (User, error)
    GetUsers() ([]User, error)
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想为测试创建模拟并仅使用一种方法。

type UserDaoMock struct { }

fucn (UserDaoMock) GetUser() (User, error) {
    return User{}
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以在测试中使用 UserDaoMock 作为 UserDao 之前不实现其他方法?告诉编译器这应该是这样的?

icz*_*cza 13

将接口嵌入UserDao到您的模拟结构中,以便它将提升所有方法。仅实现您需要的方法(实际将被调用的方法):

type UserDao interface {
    GetUser() (User, error)
    GetUsers() ([]User, error)
}

type UserDaoMock struct {
    UserDao
}

func (UserDaoMock) GetUser() (User, error) {
    return User{}, nil
}
Run Code Online (Sandbox Code Playgroud)

测试它:

var dao UserDao
dao = UserDaoMock{}
fmt.Println(dao.GetUser())
Run Code Online (Sandbox Code Playgroud)

它将输出(在Go Playground上尝试):

{} <nil>
Run Code Online (Sandbox Code Playgroud)

请注意,调用任何其他方法当然会出现恐慌,因为嵌入UserDao字段是nil,因此它们背后没有真正的实现。但UserDaoMock确实实现了UserDao,并且该GetUser()方法已实现并且可调用。

请参阅相关问题来检测哪些方法是可调用的:Go Reflection with interface嵌入在结构中 - 如何检测“真实”函数?

其他相关问题:

是否可以在 Go 中定义匿名接口实现?

Go 中嵌入式私有接口的可见性