mockery icon indicating copy to clipboard operation
mockery copied to clipboard

Mockery follows type aliases and cannot compile mock

Open conradludgate opened this issue 4 years ago • 4 comments

We have an interface with the following method

import (
	"context"
	jet "github.com/go-jet/jet/mysql"
)

type Storage interface {
	BulkUpdateValues(ctx context.Context, primaryKeys []string, values map[jet.Column]interface{}) error
}

In the jet/mysql package, Column is defined as

import "github.com/go-jet/jet/internal/jet"

// Column is common column interface for all types of columns.
type Column = jet.ColumnExpression

The generated mock uses jet.ColumnExpression from the "github.com/go-jet/jet/internal/jet" package, but since that package is internal to jet, it fails to compile.

// Code generated by mockery v2.2.1. DO NOT EDIT.

package mocks

import (
	context "context"

	jet "github.com/go-jet/jet/internal/jet"

	mock "github.com/stretchr/testify/mock"
)

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

// BulkUpdateValues provides a mock function with given fields: ctx, primaryKeys, values
func (_m *Storage) BulkUpdateValues(ctx context.Context, primaryKeys []string, values map[jet.ColumnExpression]interface{}) error {
	ret := _m.Called(ctx, primaryKeys, values)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, []string, map[jet.ColumnExpression]interface{}) error); ok {
		r0 = rf(ctx, primaryKeys, values)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

conradludgate avatar Aug 24 '20 13:08 conradludgate

I don't think we need this fix anymore, but I think it's still worth looking into - I'll attempt to fix it if I have time, unless this is intended behaviour, in which case it should probably be documented

conradludgate avatar Aug 24 '20 13:08 conradludgate

Seems to be a result of Go's own file parser. Doesn't seem easy to fix here

conradludgate avatar Aug 24 '20 14:08 conradludgate

Running into a similar issue with Context from https://github.com/temporalio/sdk-go.

jeffreyftang avatar Mar 16 '22 17:03 jeffreyftang

I also have this problem. On go1.18 and mockery 2.14

jonasberdal avatar Sep 13 '22 13:09 jonasberdal

I also have this issue. on go1.19 and mockery v2.14.0

ohadgranica avatar Oct 13 '22 08:10 ohadgranica

Also found the same issue, go 1.18 and mockery v2.14.0 But not with aliases, the bug happens with a custom type declaration (so it's very similar in my opinion)

Does this bug need a big effort to be fixed? Or it's not going to be fixed because of the developing of v3 of mockery? Could someone give a hint where the problem might be in a source code ?

alex-dwt avatar Nov 05 '22 18:11 alex-dwt

I also have this issue. on go1.19 and mockery v2.15.0

hulb avatar Dec 01 '22 03:12 hulb

I did a proof-of-concept to show how you can retrieve both the alias name and the underlying object name.

package main

import (
	"fmt"
	"go/types"
	"log"

	"golang.org/x/tools/go/packages"
)

func main() {
	pkgs, err := packages.Load(
		&packages.Config{
			Mode: packages.NeedTypesInfo |
				packages.NeedTypes |
				packages.NeedSyntax |
				packages.NeedName |
				packages.NeedTypesInfo,
			Overlay: map[string][]byte{"/hello.go": []byte(`
				package hello
				import "io"
				type testAlias = io.Reader`)}},

		"file=/hello.go")
	if err != nil {
		log.Fatal(err)
	}
	if len(pkgs) != 1 {
		log.Fatal("not one package")
	}
	pkg := pkgs[0]

	alias := pkg.Types.Scope().Lookup("testAlias").(*types.TypeName)

	// How to get underlying type info
	underlying := alias.Type().(*types.Named)
	fmt.Println(underlying.Obj().Name())
	fmt.Println(underlying.Obj().Pkg().Path())

	// How to get alias info
	fmt.Println(alias.IsAlias())
	fmt.Println(alias.Name())
	fmt.Println(alias.Pkg().Path())

}

Output

[lclipp@localhost test_golang][0] $ ./test
Reader
io
true
testAlias
command-line-arguments

I don't have the time to implement this but I strongly recommend someone submit a PR for this as it's definitely doable! The fix is likely going to be in the generator code, maybe here? https://github.com/vektra/mockery/blob/847d988fdf3765df8d39a389f58f7442de6583a5/pkg/generator.go#L334

Notice this line: https://github.com/vektra/mockery/blob/847d988fdf3765df8d39a389f58f7442de6583a5/pkg/generator.go#L336

That would resolve to the underlying type, as shown in my example. I think it would be as simple as adding a case just before that for *types.TypeName.

LandonTClipp avatar Dec 13 '22 23:12 LandonTClipp

Having the same problem in go 1.19 and mockery 2.16, on cloud.google.com/go/pubsub.Message being converted to cloud.google.com/go/internal/pubsub.Message.

This is a type alias.

type Message = ipubsub.Message

RangelReale avatar Feb 08 '23 11:02 RangelReale