Home > Software engineering >  Gomock cannot use type map[string]*mockFoo as map[string]foo
Gomock cannot use type map[string]*mockFoo as map[string]foo

Time:10-07

I am using gomock, and I have this piece of example code that I wish to test.

type StructA struct {
  client map[string]Foo
}

type Foo interface {
  foo.methodFoo() string
}

func (a *structA) MethodA(name string) string {
  client := a.client[name]
  return client.methodFoo()
  
}

In my test, i've generated a mock for foo, called mockFoo. Used mockgen v1.6.0 to generate the mock for interface foo.

I have the test code as:

func Test_MethodA(t *testing.T) {
  type fields struct {
    client map[string]*mockFoo
  }
  tests := []struct {
    fields fields
    want   string
  }
  { 
     // test cases
  }
  for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
      a := &StructA {
        client: tt.fields.client //this has an error, saying that we cannot use map[string]*mockFoo as the type map[string]foo
      }
      ...
    })
  }
}

TLDR is that map[string]*mockFoo cannot be used as the type map[string]Foo.

var foo1 Foo
var mockFoo1 *mockFoo
foo1 = mockFoo1 // no problem

var fooMap map[string]Foo
var mockFooMap map[string]*mockFoo
fooMap = mockFooMap // problematic

May I know if I'm doing anything wrong here or if this an expected behaviour? Thanks.

CodePudding user response:

Based on your description, Foo is an interface, and *mockFoo implements the Foo interface. Thus, whenever a Foo is required, you can used *mockFoo.

The type map[string]Foo is not the same as the type map[string]*mockFoo. Both are concrete types (they are not interfaces), so you cannot substitute one for the other.

You can, however, use map[string]Foo, and put *mockFoo values into that map, and as far as I can see from your code, that's what you should do. Declare the map as map[string]Foo, and use *mockFoo values in it. If you need to refer to the values of the map as *mockFoo, you can type-assert the map value to get the *mockFoo value, that is:

fooMap=map[string]Foo{}
fooMap["key"]=mockFoo1
...
value:=foomap["key"].(*mockFoo)
  • Related