Simple example.
I have package xxx. This package contains:
struct C which is an argument in method of B
type A struct {
SomeField B
}
type B interface {
SomeMethod(c C)
}
Now imagine I want to create unit test for structure A and mock dependency B. For creating mock I am using mock generator. All mocks are stored in the common "mocks" folder.
The problem is that generated mock has a dependency on xxx package. This is happening because SomeMethod of interface B has argument xxx.C.
Whenever I try to import my mock structure in a_test.go it fails because of cycle import problem. xxx package importing mocks package in the a_test.go. and mocks package imports xxx package in my generated mock.
I need a peace of advice, what is the best workaround for this? Maybe my approach is not idiomatic enough. Where do you store your mocks?
Use a top level package that all other packages import from. Put your interfaces there.
For instance:
domain/
interfaces.go
a/
mock.go
b/
mock.go
c/
mock.go
a
, b
and c
should import from domain
so they don't have any dependencies on each other. You will use duck typing to implement the interfaces of the domain
package in your mocks.
Here's an actual use case using your example:
domain/interfaces.go:
type A interface {
Foo()
}
type B interface {
Bar() string
}
type C interface {
Baz() string
}
a/mock.go:
type A struct {
SomeField domain.B
}
// ...
b/mock.go:
type B struct {
SomeMethod(c domain.C)
}
// ...
c/mock.go:
type C struct {}
// ...
That should compile just fine, because all the mocks import from the top level domain
package, and they all implement the respective interfaces.
You need to put your test under a different package.
a.go
is under package xxx
a_test.go
is under package xxx_test
a_mock.go
is under package xxx_mock
This way a_test.go
will be dependent on xxx
and xxx_mock
and will not cause dependency cycle.
Also, a.go
and a_test.go
can be under the same folder, like this:
xxx/
- a.go
- a_test.go
mock/
- a_mock.go