简单的例子。
我有包裹xxx。该软件包包含:
结构C,它是B方法中的一个参数
type A struct {
SomeField B
}
type B interface {
SomeMethod(c C)
}
Run Code Online (Sandbox Code Playgroud)现在想象一下,我想为结构A和模拟依赖项B创建单元测试。为创建模拟,我正在使用模拟生成器。所有模拟都存储在公用的“ mocks”文件夹中。
问题在于生成的模拟对xxx包具有依赖性。这是因为接口B的SomeMethod具有参数xxx.C。
每当我尝试将我的模拟结构导入a_test.go时,都会由于循环导入问题而失败。xxx程序包在a_test.go中导入了模拟程序包。并且模拟程序包在我生成的模拟程序中导入xxx程序包。
我需要一个平和的建议,对此最好的解决方法是什么?也许我的方法不够习惯。您将模拟物存储在哪里?
您需要将测试放在不同的包中。
a.go 正在打包中 xxx
a_test.go 正在打包中 xxx_test
a_mock.go 正在打包中 xxx_mock
通过这种方式a_test.go将取决于xxx和xxx_mock,不会造成依赖循环。
另外,a.go并且a_test.go可以是相同的文件夹下,这样的:
xxx/
- a.go
- a_test.go
mock/
- a_mock.go
Run Code Online (Sandbox Code Playgroud)
自从
都在同一个包中,该接口应被视为“包内”接口,对于其他包中的代码是不可见的。因此,该接口的模拟应该与接口本身位于同一包中。
结论:
将它们全部放在同一个包中。
因此,将gomock生成的mock代码放入与接口相同的包中,而不是“mock”包中。示例(Windows版本):
mockgen -source=.\foo\bar.go -destination=.\foo\bar_mock.go -package=foo
Run Code Online (Sandbox Code Playgroud)
使用所有其他包从中导入的顶级包。把你的接口放在那里。
例如:
domain/
interfaces.go
a/
mock.go
b/
mock.go
c/
mock.go
Run Code Online (Sandbox Code Playgroud)
a,b并且c应该从中导入,domain这样它们就不会相互依赖。您将使用鸭子类型来实现模拟中包的接口domain。
这是使用您的示例的实际用例:
域/interfaces.go:
type A interface {
Foo()
}
type B interface {
Bar() string
}
type C interface {
Baz() string
}
Run Code Online (Sandbox Code Playgroud)
a/mock.go:
type A struct {
SomeField domain.B
}
// ...
Run Code Online (Sandbox Code Playgroud)
b/mock.go:
type B struct {
SomeMethod(c domain.C)
}
// ...
Run Code Online (Sandbox Code Playgroud)
c/mock.go:
type C struct {}
// ...
Run Code Online (Sandbox Code Playgroud)
这应该可以很好地编译,因为所有模拟都从顶级domain包导入,并且它们都实现了各自的接口。
| 归档时间: |
|
| 查看次数: |
1112 次 |
| 最近记录: |