petergtz / pegomock

Pegomock is a powerful, yet simple mocking framework for the Go programming language
Apache License 2.0
252 stars 28 forks source link

Pegomock resolves real type instead of alias type #117

Open jpopadak opened 3 years ago

jpopadak commented 3 years ago

Creating Pegomock Matchers or Mocks for a type which is an alias for a private ./internal/ package type causes compile errors upon matcher creation.

Setup In the example below, status.Status is a type alias denoted here in their code.

File: ./myfile.go

package mypkg

import (
    "google.golang.org/grpc/status"
)

//go:generate ${PEGOMOCK} generate -m mypkg MyInterface

type MyInterface interface {
    MyFunction(s *status.Status)
}

Result When generating a matcher, it instead generates a file using the ./internal/. package path instead of the public one.

The resulting matcher file has this header, referencing the internal package. File: ./matchers/ptr_to_status_status.go

// Code generated by pegomock. DO NOT EDIT.
package matchers

import (
    "github.com/petergtz/pegomock"
    "reflect"

    status "google.golang.org/grpc/internal/status"
)

// ... more Matcher code

The same occurs for the Mock itself. File: ./mock_myinterface_test.go

// Code generated by pegomock. DO NOT EDIT.
// Source: mypkg (interfaces: MyInterface)

package mypkg_test

import (
    pegomock "github.com/petergtz/pegomock"
    status "google.golang.org/grpc/internal/status"
    "reflect"
    "time"
)

// ... more Matcher code

Thoughts Is this a limitation around how the types are resolved? Or do we try to find the alias type to place in here?

jpopadak commented 3 years ago

One thing to note, this has been happening for a while (not a recent issue / version). My team worked around it by creating their own mock & matchers with the correct type. They copied and pasted the generated ones from Pegomock & changed the imports. Those mocks are still being used today. 😄

petergtz commented 3 years ago

Hey @jpopadak, is this a duplicate of https://github.com/petergtz/pegomock/issues/64?

jpopadak commented 3 years ago

It is not. Surprisingly, the generation of code "works" and doesn't fail when creating the intermediary prog.go.

Instead, it's failing on building of the generated files.

The issue here is the incorrect import is used for the type. In the generated file, the concrete type which alias points to is used in the import statement. However, the concrete type exists within internal.

This can be fixed by instead of using the type the alias points to, to use the alias type itself (which exists outside of the internal package).

petergtz commented 3 years ago

Ah, yes, sorry, now I'm getting it.

Is this a limitation around how the types are resolved? Or do we try to find the alias type to place in here?

It could be a limitation, yes. The code to find the types was potentially written even before type aliases existed, but I haven't checked. Have you check if this still doesn't work when using the --use-experimental-model-gen option? Since that uses a completely different mechanism to introspect interfaces and types, it's possible this gives you different results.

jpopadak commented 3 years ago

I just tried it with the --use-experimental-model-gen flag and the same issue occurs (both the Matcher and the Mock).