Reputation: 16024
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.
Upvotes: 0
Views: 1139
Reputation: 16024
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.
Upvotes: 0
Reputation: 4623
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
Upvotes: 1
Reputation: 135
You will need to call the otherMethod()
inside init()
. It can't be called before init()
otherwise.
Upvotes: 0