Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
115 views
in Technique[技术] by (71.8m points)

Where/how to construct objects in a go project with unit tests

I've recently been working on Go project. In order to allow each component to be unit testable, I've been following the pattern specified in several articles to change functions like:

func WriteObject(obj ObjType) {
   dbClient := DBClient{}
   dbClient.WriteObject(obj)
}  

to be like:

type WriteObject interface {
   WriteObject(obj ObjType)
}

type ProxyWriteObject struct {
   dbClient DBClientInterface
}

func (p * ProxyWriteObject) WriteObject(obj ObjType) {
   p.dbClient.WriteObject(obj)
}

so that i can then mock the dbClient during testing. My question is, if I use this approach, I'll have a bunch of components that all depend on interfaces. Where should the instances of the objects that implement these interfaces be constructed? The most obvious thing seem to be to have the top level objects that are not depended on by any others construct their dependencies and all the dependency's dependencies etc, but this would be very messy.

I've worked primarily in Java, so typically I'd use Dagger/Guice/Spring to construct and inject the objects. Is there a similar or recommended DI framework in Go, or what is the recommended approach to construct these objects?

question from:https://stackoverflow.com/questions/65649892/where-how-to-construct-objects-in-a-go-project-with-unit-tests

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A simple solution to this would be:

type DBClientIntf interface {
   WriteObject(ObjType)
}

func WriteObject(obj ObjType,cli DBClientIntf) {
  cli.writeObject(obj)
}

Or, you can have a factory:

func WriteObject(obj ObjType,cli func() DBClientIntf) {
  cli().writeObject(obj)
}

Or, a global factory:

var getDBClient=func() DBClientIntf {
   return DBClient{}
}

func WriteObject(obj ObjType) {
  getDBClient().writeObject(obj)
}

and set the global factory to a function that returns a mocked client:

func TestWriteObject(t *testing.T) {
   getDBClient=func() DBClient {
     return mockDBClient{}
  }
  ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...