Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version
  1. Define the Interface of the Database

The first step in using dependency injection in Golang is to define an interface for the database. This interface will be implemented by the actual database as well as the mock database.

type Database interface { GetUserById(string) (User, error) SaveUser(User) error }

  1. Implement the Database

Next, implement the actual database. For example, you might use MongoDB or PostgreSQL. Implement the methods defined in the interface you created in step 1.

type MongoDB struct { ... }

func (db MongoDB) GetUserById(id string) (User, error) { ... }

func (db *MongoDB) SaveUser(user *User) error { ... }

  1. Implement the Mock Database

Now, create a mock database by implementing the database interface. The mock database should return predetermined values for the methods in the interface.

type MockDatabase struct { ... }

func (db MockDatabase) GetUserById(id string) (User, error) { return &User{"mockFirstName", "mockLastName", 30}, nil }

func (db *MockDatabase) SaveUser(user *User) error { return nil }

  1. Instantiate the Database

In your code, create an instance of the database interface. In production, you would create an instance of the actual database. In unit tests, you would create an instance of the mock database.

func main() { db := &MongoDB{} ... }

func TestGetUserById(t *testing.T) { db := &MockDatabase{} ... }

  1. Pass the Database as a Dependency

Finally, pass the database instance created in step 4 as a dependency to the function or method being tested.

func GetUserById(db Database, id string) (*User, error) { ... }

In production, pass the actual database instance. In unit tests, pass the mock database instance.

user, err := GetUserById(db, "123") // user will be the mock user defined in the mock database implementation.

With this approach, you can easily swap out the database implementation with a mock database for unit testing.