When I started writing tests in Go, I sometimes used interfaces to mock things in tests. Then I discovered that this is not the correct way:
Similar to github.com:karantan/go-concurrency, I decided to create (another) "lessons learned/good practices" repo that shows how to accepting interfaces and returning structs in practice.
Preemptive abstractions make systems complex.
I won't explain in detail why it's a bad practice to return interfaces because it's already been explained in the posts linked above. Please read them before going through the code here.
Additional resources: