golang / mock

GoMock is a mocking framework for the Go programming language.
Apache License 2.0
9.26k stars 608 forks source link

Source mode fails with embedded interfaces in a specific case #85

Closed pasztorpisti closed 6 years ago

pasztorpisti commented 7 years ago

Here are my test files (2 packages):

github.com/anyuser/pkg1/pkg1.go:

package pkg1

type I interface {
    E
}

type E interface {
    M()
}

github.com/anyuser/pkg2/pkg2.go:

//go:generate mockgen -source pkg2.go -destination pkg2_mock.go -package pkg2 -aux_files pkg1=../pkg1/pkg1.go
package pkg2

import "github.com/pasztorpisti/pkg1"

type I interface {
    pkg1.I
}

If you run go generate on pkg2 then you get the following error message:

2017/06/27 18:03:01 Loading input failed: ../pkg1/pkg1.go:4:2: unknown embedded interface E
pkg2.go:1: running "mockgen": exit status 1

Note that mock generation succeeds if you go to pkg1 and embed the E interface into I by prefixing it with the package name pkg1.E but that turns pkg1.go into invalid go code that doesn't compile.

JeremyLoy commented 6 years ago

This also works in the following scenario:

github.com/anyuser/pkg1/file1.go


type A interface {
    Method1()
}

github.com/anyuser/pkg1/file2.go


type B interface {
    A
}

Just to make explicit the difference here: Two separate files, but same package produces the same issue.

mockgen -source=pkg1/file2.go -package pkg1 -aux_files pkg1=pkg1/file1.go -destination pkg1/file2_mock.go

The above produces the 'unknown embedded interface' error.

It can also be resolved as you described, by the following:

type B interface {
    pkg1.A
}

But again, thats invalid Golang code.

JeremyLoy commented 6 years ago

Looking into it more, I found this TODO in the source code.

https://github.com/golang/mock/blob/747e9e6390e12b0d987c261bdc89a51e76b9f5fc/mockgen/mockgen.go#L18

balshetzer commented 6 years ago

Both given examples above work now.

amatoenot commented 6 years ago

@balshetzer Just checked. Not working. The only way to solve this case is to use reflect mode.

balshetzer commented 6 years ago

As I said in #178, The aux_files flag needs to specify the full package path.