Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
114 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 Reply

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{}
  }
  ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...