I'm writing some code that uses a library called Vault. In this library we have a Client
. My code makes use of this Client
but I want to be able to easily test the code that uses it. I use only a couple methods from the library so I ended up creating an interface:
type VaultClient interface {
Logical() *api.Logical
SetToken(v string)
NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)
}
Now if my code is pointed at this interface
everything is easily testable.. Except let's look at the Logical()
method. It returns a struct
here. My issue is that this Logical
struct also has methods on it that allow you to Read
, Write
, ex:
func (c *Logical) Read(path string) (*Secret, error) {
return c.ReadWithData(path, nil)
}
and these are being used in my project as well to do something like:
{{ VaultClient defined above }}.Logical().Write("something", something)
Here is the issue. The Logical
returned from the call to .Logical()
has a .Write
and .Read
method that I can't reach to mock. I don't want all the logic within those methods to run in my tests.
Ideally I'd like to be able to do something similar to what I did above and create an interface
for Logical
as well. I'm relatively new to Golang, but I'm struggling with the best approach here. From what I can tell that's not possible. Embedding doesn't work like inheritance so it seems like I have to return a Logical
. That leaves my code unable to be tested as simply as I would like because all the logic within a Logical
's methods can't be mocked.
I'm sort of at a loss here. I have scoured Google for an answer to this but nobody ever talks about this scenario. They only go as far as I went with the initial interface
for the client.
Is this a common scenario? Other libraries I've used don't return struct
s like Logical
. Instead they typically just return a bland struct
that holds data and has no methods.