I face similar problems in a lot of production Go code which I write. I do
have an answer for this, but it's not pretty. Your code would look
something like this:

type ResourceGetter interface {
    GetResource(id string) (*Resource, error)
}

type ResourceManagerImpl struct {
  rg ResourceGetter
}

func (r *ResourceManagerImpl) GetResource(id string) (*Resource, error) {
  return r.rg.GetResource(id)
}

Then, you'd move your implementation of GetResource to ResourceGetterImpl.
You can then stub in a mock ResourceGetter in your test, and the
GetAllResources function is none the wiser.

Using so many interfaces has a nice side effect - I can pass things around
using their minimal function footprint to make the code generally easier to
refactor and test.

-- Marcin


On Thu, Dec 12, 2019 at 2:29 PM <karthik3...@gmail.com> wrote:

> I am having trouble writing unit tests in Go for a rather common
> use-case/pattern.
>
>
> Imagine, if you will, something like this:
>
>
> package main
>
> type Resource struct {
>     name string}
>
> type ResourceManager interface {
>     GetResource(id string) (*Resource, error)
>     GetAllResources() ([]*Resource, error)}
>
> type ResourceManagerImpl struct {}
>
> func (r *ResourceManagerImpl) GetResource(id string) (*Resource, error) {
>     resource := &Resource{}
>     var err error
>
>     // fetch resource.
>     // ...
>
>     return resource,  err}
>
> func (r *ResourceManagerImpl) GetAllResources() ([]*Resource, error) {
>     var resources []*Resource
>     var err error
>
>     // for _, id := range ids {
>     //  resource = r.GetResource(id)
>     //  resources = append(resources, resource)
>     // }
>
>     return resources, err}
>
>
> It's a common pattern to have the GetAllResources invoke GetResource 
> repeatedly
> as-needed.
>
>
> I can use gomock or testify to test all permutations of GetResource. But,
> when testing GetAllResource, I'd like to mock GetResource. Otherwise,
> testing would become sort-of-a nightmare. This is how one would do it in
> easymock or mockito in case of Java using partial mocks. But, it's not
> clear how the same could be achieved in Golang.
>
>
> Specifically, I couldn't find how to partially mock the struct. Most
> suggestions revolve around breaking such structs but in this case, the
> struct is already at its bare minimum. It seems like a fair ask to not
> break the ResourceManager interface (into single and multi) for the sake
> of testing as that would not make much sense and would be kludgy at best
> and wouldn't scale well as more such methods make into the interface.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/3c22e3fc-b3ad-47e7-9e41-400856423e58%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/3c22e3fc-b3ad-47e7-9e41-400856423e58%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LugB4w4LL8ce7L-Wy5PR7mfjKTtjOBr3r5%3DNTik8evfrA%40mail.gmail.com.

Reply via email to