matryer / moq

Interface mocking tool for go generate
http://bit.ly/meetmoq
MIT License
1.9k stars 125 forks source link

moq generates mocks with internal package imports #153

Open d-lowl opened 3 years ago

d-lowl commented 3 years ago

In some situations, moq generates mocks that try to import internal 3rd party packages. Minimal example below.

example.go

package app

import (
    "context"

    pubsub_api "cloud.google.com/go/pubsub"
)

type IPubSubTopic interface {
    Exists(ctx context.Context) (bool, error)
    Publish(ctx context.Context, msg *pubsub_api.Message) *pubsub_api.PublishResult
}

Here pubsub_api is an explicit alias to the public package.

Generate mock:

moq -out example_mock.go . IPubSubTopic

example_mock.go

// Code generated by moq; DO NOT EDIT.
// github.com/matryer/moq

package app

import (
    "cloud.google.com/go/internal/pubsub"
    "context"
    "sync"
)

// Ensure, that IPubSubTopicMock does implement IPubSubTopic.
// If this is not the case, regenerate this file with moq.
var _ IPubSubTopic = &IPubSubTopicMock{}

But the mock imports the internal pubsub package instead. I couldn't find any way to prevent it.

go version go1.15.6 linux/amd64 moq version: v0.2.3

sudo-suhas commented 3 years ago

The problem is around adding the import for a type alias - googleapis/google-cloud-go@pubsub/v1.15.0/pubsub/message.go#L37.

I have added a test case for the same in #155. For some reason, while parsing the interface method's parameters, the type information has the package as the original package instead of the one where it was aliased:

image

As it happens, this issue affects github.com/vektra/mockery as well:

moq/pkg/moq/testpackages on  master [$!?] via 🐹 v1.16.5 using ☁️  default/
➜ mockery --dir typealiaspkgimport --name Processor --print
21 Aug 21 15:10 IST INF Starting mockery dry-run=false version=2.9.0
21 Aug 21 15:10 IST INF Walking dry-run=false version=2.9.0
21 Aug 21 15:10 IST INF Generating mock dry-run=false interface=Processor qualified-name=github.com/matryer/moq/pkg/moq/testpackages/typealiaspkgimport version=2.9.0
// Code generated by mockery 2.9.0. DO NOT EDIT.

package mocks

import (
    message "github.com/matryer/moq/pkg/moq/testpackages/typealiaspkgimport/internal/message"
    mock "github.com/stretchr/testify/mock"
)

// Processor is an autogenerated mock type for the Processor type
type Processor struct {
    mock.Mock
}

// Process provides a mock function with given fields: msg
func (_m *Processor) Process(msg message.Message) error {
    ret := _m.Called(msg)

    var r0 error
    if rf, ok := ret.Get(0).(func(message.Message) error); ok {
        r0 = rf(msg)
    } else {
        r0 = ret.Error(0)
    }

    return r0
}
dantonio-nyt commented 2 years ago

has there been any progress with this issue? I'm experiencing the same problem with imports

sudo-suhas commented 2 years ago

I had tried asking for help on Gophers slack as well but I was not able to use the suggestions to arrive at a solution for the problem of type alias information - https://gophers.slack.com/archives/C0VPK4Z5E/p1629540208130200

breml commented 2 years ago

I did ask on Slack as well and I have been pointed to an older discussion about the same topic as well as this issue on https://github.com/golang/mock/issues/244. As far as I can tell, there is no issue on the Go issue tracker so I am not sure if there is already general awareness of this issue.

Currently it looks like the only way to solve this would be to change the processing of moq such that it primarily processes ast exressions and the resolves these to types (see the above linked discussion).

papadeltasierra commented 6 months ago

Very late to the game but hit this error and I have a problem that this does not solve. I have multiple packages that mockery maps down to a single internal package and I cannot use the --replace-type command-line parameter to replace back to those packages. So what happens is:

mockery follows packages A, B, C to internal package Z I can use replace-type to map Z to A, or B, or C but not all of them!

The package that causes this is not mine and I cannot fix it so seem unable to use mockery to mock my interface.

K4L1Ma commented 5 months ago

https://github.com/matryer/moq/pull/213