Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocking in a different package breaks unexported methods #199

Closed
adam-hanna opened this issue Aug 15, 2024 · 1 comment
Closed

Mocking in a different package breaks unexported methods #199

adam-hanna opened this issue Aug 15, 2024 · 1 comment

Comments

@adam-hanna
Copy link

adam-hanna commented Aug 15, 2024

Requested feature
Say you have the following project structure:

main.go
foo/
  interface.go

And inside /foo/interface.go you have:

// foo/interface.go
package foo

type IFoo interface {
  Bar() int
  baz()
}

And you try to mock it into your main (or any package other than foo):
$ mockgen -source=foo/interface.go -destination=mock.go -package=main

And then you try to use it:

// main.go
package main

import (
	"github.com/adam-hanna/mock-test/foo"
)

func main() {
	mockedFoo := MockIFoo{}
	doBar(&mockedFoo)
}

func doBar(f foo.IFoo) {
	f.Bar()
}

You will get the error: cannot use &mockedFoo (value of type *MockIFoo) as foo.IFoo value in argument to doBar: *MockIFoo does not implement foo.IFoo (unexported method baz)compilerInvalidIfaceAssign

Demo, here.

If you were to mock into the foo package, everything is fine, but this isn't always possible.

Why the feature is needed
This is needed if you are trying to mock a 3rd party library, and cannot modify their source code to add a mock. This happens to me all of the time when I'm writing tests and need to mock a 3rd party dependency.

(Optional) Proposed solution
The fix is quite simple. The created struct just needs to imbed the mocked interface. In my example:

// MockIFoo is a mock of IFoo interface.
type MockIFoo struct {
        foo.IFoo
	ctrl     *gomock.Controller
	recorder *MockIFooMockRecorder
}

I don't believe doing this will break any existing code.

We may also need to add a flag for the dependency location foo. For example, if foo wasn't local, but was at github.com/adam-hanna/foo we would need to add that to the imports.

@JacobOaks
Copy link
Contributor

Thanks for the issue, but I think this is a duplicate of #64 so I'll close it. Please let me know if I'm mistaken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants