Pkg.go.dev is a new destination for Go discovery & docs. Check it out at pkg.go.dev/github.com/dradtke/stubber and share your feedback.

Command stubber

Stubber is a tool to automate the creation of "stubbed" interface implementations.

An interface's stubbed implementation is a struct, satisfying the interface, that contains one field for each of the interface's methods. When one of these methods is called, it uses the backing field as its implementation, or panics if none was defined. This allows the behavior of the stub to be modified at run-time in a type-safe way, while only requiring you to define the methods that will actually be called.

For example, given this simple interface:

type SessionManager interface { GetUserID(db *sql.DB, username string) (int64, error) }

Then its stub would look like this:

type StubbedSessionManager struct { GetUserIDStub func(db *sql.DB, username string) (int64, error) getUserIDCalls []struct { Db *sql.DB Username string } } func (s *StubbedSessionManager) GetUserID(db *sql.DB, username string) (int64, error) { if s.GetUserIDStub == nil { panic("StubbedSessionManager.GetUserID: nil method stub") } s.getUserIDCalls = append(s.getUserIDCalls, struct { Db *sql.DB Username string }{Db: db, Username: username}) return (s.GetUserIDStub)(db, username) } func (s *StubbedSessionManager) GetUserIDCalls() []struct { Db *sql.DB Username string } { return s.getUserIDCalls }

Note that StubbedSessionManager implements the SessionManager interface, and that its implementation of GetUserID() uses the backing field GetUserIDStub.

Here's an example of how it would be used in a test:

func TestSomething(t *testing.T) { sm := &StubbedSessionManager{ GetUserIDStub: func(db *sql.DB, username string) (int64, error) { return 0, nil // or whatever implementation you want }, } // Use sm here anywhere a SessionManager is accepted }

Assuming the rest of your code is built around an actual implementation of SessionManager, and that your methods take their dependent resources as parameters, then this provides an easy way to mock out service calls, but in an easy-to-understand, type-safe manner.

See the example folder for more information.

stubber.go