英文:
Golang: Mock an interface method before Init method is called
问题
如何模拟在包的init()
方法中调用的内容?
例如:
main.go
var myService MyService = myservicepkg.New()
func init(){
response := myService.get()
}
func otherMethod(){
//do something
}
maintest.go
func Test_otherMethod(){
ctrl := NewController(t)
defer ctrl.Finish()
myServiceMock = myservicepkg.NewMock(myService)
myServiceMock.EXPECT().get().return("success")
}
问题是在服务被模拟替换之前,init()
方法就已经被调用了。
英文:
How can I mock something that gets called in a package init()
method?
For example:
main.go
var myService MyService = myservicepkg.New()
func init(){
response := myService.get()
}
func otherMethod(){
//do something
}
maintest.go
func Test_otherMethod(){
ctrl := NewController(t)
defer ctrl.Finish()
myServiceMock = myservicepkg.NewMock(myService)
myServiceMock.EXPECT().get().return("success")
}
The problem is that init()
is called before the service is replaced by the mock.
答案1
得分: 1
这是一个涉及可变全局状态的问题。
我的建议是添加一个标志,以便在特定条件下不运行此代码,或者公开一个私有函数,可以在内部测试中恢复/更新此全局变量。
这反映了你的设计:如果测试很复杂,也许你应该进行重构。
创建一个名为Application的对象,其中包含一个字段Service,在构造函数/构建器/工厂中创建将更容易进行测试。
init的使用非常微妙。除了将驱动程序注册到sql包中,我从来没有使用过它(也许用于处理标志)。
也许你可以在你的设计中添加更多面向对象的特性。
英文:
This is the issue of work with a mutable global state.
My advice is to add a flag to not run this on certain conditions or expose a private function that can recover/update this global variable in an internal test.
This reflects your design: if it is complicate to test, perhaps you should refactor.
Create an object Application with a field Service, created on the constructor/builder/factory will be easier to test.
The usage of init is very delicate. Besides register a driver into sql packages, I never use it (perhaps to handle flags).
Perhaps you can add more OO to your design
答案2
得分: 0
你需要在init()
函数内部调用otherMethod()
。否则,在init()
之前不能调用它。
英文:
You will need to call the otherMethod()
inside init()
. It can't be called before init()
otherwise.
答案3
得分: 0
我找到了一个解决方法,你可以通过以下方式阻止初始化代码在测试中被执行,并独立测试该方法:
func init(){
if len(os.Args) > 0 && strings.HasSuffix(os.Args[0], ".test") {
log.Printf("skipping jwt.init() for testing")
} else if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "-test.run") {
log.Printf("skipping jwt.init() for testing")
} else {
response := myService.get()
}
}
这样可以防止初始化服务调用被执行。
英文:
I found a workaround, you can prevent the init code from being executed in your test and test the method in isolation like this:
func init(){
if len(os.Args) > 0 && strings.HasSuffix(os.Args[0], ".test") {
log.Printf("skipping jwt.init() for testing")
} else if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "-test.run") {
log.Printf("skipping jwt.init() for testing")
} else {
response := myService.get()
}
}
This will prevent the init service calls from being called.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论