jeudi 2 mai 2019

IoC in Golang: how do I inject interfaces?

I'm trying to understand the best pattern to inject interfaces in go. I'm completely open to the possibility that I'm trying to abuse a model that just doesn't work in go, but I can't figure out what the cleanest solution would be.

Let's say I have a set of functions in the "foo" package that depend on a set of interfaces defined in the "bar" package. Let's use the example of trying to inject different persistent stores into a set of services.

So in "bar"

package bar

type DatabaseOne interface {
    Read() (string, error)
    Write() error
}

type DatabaseOneClient struct {
    Conn *db.ConnectionPool
}

func (client *DatabaseOneClient) Read() (string, error) { ... }
func (client *DatabaseOneClient) Write() error { ... }

Now, in "foo" I want to use this (and many more) client. So

package foo

import (
    "bar"
)

func DoSomething(dbClient *bar.DatabaseOneClient) {
    dbClient.Read()
    ...
}

The above is my current structure. The problem is that I can't inject a DatabaseOneClient mock, since DoSomething expects the struct.

I'm not sure how I would inject the interface. Should I create a new interface that contains all my potential clients and then implement that giant interface in my foo package? Basically, I want to do the following:

func DoSomething(dbClientOne *bar.DatabaseOne, dbClientTwo *bar.DatabaseTwo, dbClientThree *bar.DatabaseThree)

Then I can just create a mock Database in my test file...

I feel like I'm thinking about this in entirely the wrong way, but I don't understand the go way of doing this.

I'd appreciate insights. Thanks!

Aucun commentaire:

Enregistrer un commentaire