Mocking Interfaces Golang I thought of doing the following to mock/test functions in Go and wanted some advice. Let's say you have an interface for a repository:
    type Creator interface {
        CreateUser(User) (*User, error)
    }
    
    type Updater interface {
        UpdateUser(User) (*User, error)
    }
    
    type Retreiver interface {
        GetUserByEmail(string) (*User, error)
        GetUserByID(uint) (*User, error)
    }
    
    type Repository interface {
        Creator
        Updater
        Retreiver
    }

The mock interface implements the Repository interface. It provides mock functions that can be swapped out depending on the test:
type MockUserRepo struct {
    CreateUserMock     func(user.User) (*user.User, error)
    UpdateUserMock     func(user.User) (*user.User, error)
    GetUserByEmailMock func(string) (*user.User, error)
    GetUserByIDMock    func(uint) (*user.User, error)
}

func (m *MockUserRepo) CreateUser(u user.User) (*user.User, error) {
    return m.CreateUserMock(u)
}

func (m *MockUserRepo) UpdateUser(u user.User) (*user.User, error) {
    return m.UpdateUserMock(u)
}

func (m *MockUserRepo) GetUserByEmail(s string) (*user.User, error) {
    return m.GetUserByEmailMock(s)
}

func (m *MockUserRepo) GetUserByID(i uint) (*user.User, error) {
    return m.GetUserByIDMock(i)
}

Then in the test function, you can create a mock for the single function that can be called. This can sometimes cause a nil pointer error if the function wasn't implemented/mocked by the testcase.
mockUserRepo := &amp;MockUserRepo{
    GetUserByEmailMock: func(s string) (*user.User, error) {
        return nil, user.ErrUserDoesNotExist
   },
}

Any thoughts on if this is a bad/good practice?
This seems fine to me: it's nice and simple, and I've seen this pattern used &quot;in the wild&quot; before. One thing you could do is, in the MockUserRepo proxying functions, if the function variable is nil, either execute a default implementation, or return a more specific error (or even panic). For example:
func (m *MockUserRepo) GetUserByEmail(s string) (*user.User, error) {
    if m.GetUserByEmailMock == nil {
        // default implementation: return a dummy user object
        return &amp;user.User{ID: generateID(), Email: s}, nil
    }
    return m.GetUserByEmailMock(s)
}

// or:

func (m *MockUserRepo) GetUserByEmail(s string) (*user.User, error) {
    if m.GetUserByEmailMock == nil {
        // default implementation: panic with a more specific error
        panic(&quot;MockUserRepo: GetUserByEmail not set&quot;)
    }
    return m.GetUserByEmailMock(s)
}

The reason I'd be okay with a panic here is because not setting GetUserByEmail is almost certainly a coding bug in the test, not really a runtime error condition. This latter approach doesn't gain you much over just letting the nil pointer access panic, except that the error message is a bit more specific.