Go use struct as interface without implementing all methods

Issue

For example i have dao with 20 methods.

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

And i want create mock for tests and use only one method.

type UserDaoMock struct { }

fucn (UserDaoMock) GetUser() (User, error) {
    return User{}
}

There is a way to don’t implements other methods before using UserDaoMock as a UserDao in tests? Tell the compiler that this is how it should be?

Solution

Embed the UserDao interface in your mock struct, so it will have all the methods promoted. Implement only the methods you need (the methods that will actually be called):

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

type UserDaoMock struct {
    UserDao
}

func (UserDaoMock) GetUser() (User, error) {
    return User{}, nil
}

Testing it:

var dao UserDao
dao = UserDaoMock{}
fmt.Println(dao.GetUser())

Which will output (try it on the Go Playground):

{} <nil>

Note that calling any other methods would panic of course, because the embedded UserDao field is nil, so there is no real implementation behind them. But UserDaoMock does implement UserDao, and the GetUser() method is implemented and is callable.

See related question to detect which methods are callable: Go reflection with interface embedded in struct – how to detect "real" functions?

Other related questions:

Is it possible to define an anonymous interface implementation in Go?

Visibility of embedded private interfaces in Go

Answered By – icza

Answer Checked By – Clifford M. (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.