jcgrowley
jcgrowley

Reputation: 759

Golang test package circular dependency problem

Suppose I have two packages, foo and bar (and thus, foo.go, foo_test.go, bar.go, and bar_test.go.) bar depends on foo. In bar_test.go, I want to use some faked types that are defined in foo_test.go. But since it isn't allowed for *_test.go files to export types, I moved them into a test package for foo, ie footest, that both foo and bar depend on.

Suppose foo.go has some interfaces like this:

type A interface {
   AFunc() err
}

type B interface {
   BFunc() (A, error)
}

and in footest.go, I want to implement these interfaces with fakes:

type FakeA struct {}

type FakeB struct {}

func (fa *FakeA) AFunc() error {
   // this does something
}

func (fb *FakeB) BFunc() (A, error) {
   // this does something and returns an instance of A
}

This doesn't work, because it creates a circular dependency. foo depends on footest, but footest also needs to depend on foo in order to reference A.

Am I missing some kind of best practice that would enable me to avoid this problem? I was under the impression that creating test packages, like footest, is the standard practice when test files need to use faked types in other packages, but I would love to be corrected if there's a better way.

Upvotes: 1

Views: 2499

Answers (1)

A.Khan
A.Khan

Reputation: 3992

package foo will not depend on package footest as long as you use package foo_test in your foo_test.go file. In that case, foo_test will be compiled as a separate package. However, you won't have access to non-exported types in package foo.

e.g.

foo.go

package foo

type A interface {
   AFunc() err
}

type B interface {
   BFunc() (A, error)
}

foo_test.go

package foo_test

// Add tests after importing package footest and foo

Read this answer for more details on the package naming.

Upvotes: 7

Related Questions