I am trying to mock out the MongoDB client library mgo. This library does not seem to use interfaces to define access to its library, so I am trying to mock out the methods our code uses. The problem is when I have a struct that implements a method, but the signature doesn’t match. Easier to grok from the code
Example
type IFoo interface {
foo() IBar
}
type IBar interface {
bar()
}
func TakeMyInterface(x IFoo) {
x.foo().bar()
}
// **********
type SomeUsefulThing struct{}
func (x *SomeUsefulThing) foo() *SomeUsefulThing {
fmt.Print("SomeUsefulThing::foo was called")
return x
}
func (x *SomeUsefulThing) bar() {
fmt.Print("SomeUsefulThing::bar was called")
}
// **********
type MockSomeUsefulThing struct{}
func (x *MockSomeUsefulThing) foo() *MockSomeUsefulThing {
fmt.Print("MockSomeUsefulThing::foo was called")
return x
}
func (x *MockSomeUsefulThing) bar() {
fmt.Print("MockSomeUsefulThing::bar was called")
}
// ********
func main() {
x := &MockSomeUsefulThing{}
x.foo().bar()
TakeMyInterface(x) <-- This is where I see the error
}
ERROR:
cannot use x (type *MockSomeUsefulThing) as type IFoo in argument to TakeMyInterface:
*MockSomeUsefulThing does not implement IFoo (wrong type for foo method)
have foo() *MockSomeUsefulThing
want foo() IBar
So my problem seems to be that the signature
func (x *MockSomeUsefulThing) foo() *MockSomeUsefulThing
is not the same as
func (x *MockSomeUsefulThing) foo() IBar
But I thought this should work because MockSomeUsefulThing really does implement IBar.
Any thoughts on this would be helpful, since I thought this was a perfectly rational thing to do in Go.