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

mockery fails to generate mocks for interfaces that use generics #451

Closed
LandonTClipp opened this issue Apr 19, 2022 · 6 comments · Fixed by #456
Closed

mockery fails to generate mocks for interfaces that use generics #451

LandonTClipp opened this issue Apr 19, 2022 · 6 comments · Fixed by #456

Comments

@LandonTClipp
Copy link
Collaborator

Description

This is a meta ticket to track issues with 1.18 generics.

#442
#439

Version

2.11.0

@Gevrai
Copy link

Gevrai commented Apr 20, 2022

I'd be interested in taking a crack at this issue, if no one else is.

It means bumping the project to go 1.18 though, do you foresee any issue with this? It means that anyone compiling from source would need to have go 1.18 compiler I think.

@LandonTClipp
Copy link
Collaborator Author

Thanks for volunteering @Gevrai . I have been debating this internally, supporting generics is a backwards-incompatible change since we'd need to bump to go 1.18 as you mentioned. However, I have been pushing people to not go install mockery as it becomes dependent on the version of mockery installed and thus would fail if the project uses a language feature from a version they don't have installed. Downloading from the pre-built binaries is the best option.

There might be a way around this with build tags. I am wondering if we can exclude certain golang files based on the version of golang used for building?

@cruickshankpg
Copy link
Contributor

Sorry @Gevrai I missed your comment and made my own attempt at this

@AntonioYuen
Copy link

+1

@Gevrai
Copy link

Gevrai commented Apr 21, 2022

Sorry @Gevrai I missed your comment and made my own attempt at this

Hey no worries !

If that might be of any help, I tried to figure out an interface which should cover all potential issues that would arise with generating mocks for a Generic interface with odd constraints. It might be valuable to split into many interfaces instead though 😅

I might have missed some cases as well.

type RequesterGenerics[
	TAny any,
	TComparable comparable,
	TSigned constraints.Signed, // external constraint
	TIntf GetInt, // internal interface
	TExternalIntf io.Writer, // external interface
	TGenIntf GetGeneric[TSigned], // generic interface
	TInlineType interface{ ~int | ~uint }, // inlined interface constraints
	TInlineTypeGeneric interface {
		~int | GenericType[int, GetInt]
	}, // inlined type constraints
	TInlineIntf interface{ Get() int }, // inlined interface definition
] interface {
	GenericArguments(TAny, TComparable) (TSigned, TIntf)
	GenericStructs(GenericType[TAny, TIntf]) GenericType[TSigned, TIntf]
	GenericStructsSpecificType(GenericType[int, TInlineIntf]) GenericType[TInlineType, interface{ Get() int }]
	GenericStructsMix(GenericType[string, GetGeneric[int]]) GenericType[int, TInlineIntf]
	GenericAnonymousStructs(struct{ Type1 TExternalIntf }) struct {
		Type2 GenericType[string, EmbeddedGet[int]]
	}
}

type GenericType[T any, S GetInt] struct {
	Any  T
	Some []S
}

type GetInt interface{ Get() int }

type GetGeneric[T constraints.Integer] interface{ Get() T }

type EmbeddedGet[T constraints.Signed] interface{ GetGeneric[T] }

@cruickshankpg
Copy link
Contributor

That's a more complete set than I was using and have moved my tests to use it thanks. I had missed union types and embedded generic types with type arguments and have now added support.

I have dropped the inlined interfaces with methods though as mockery does not currently support them and I think that's a separate line of work to this.

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

Successfully merging a pull request may close this issue.

4 participants