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

Generate mocks for interfaces with generic types #173

Closed
lucastorri opened this issue Apr 6, 2022 · 5 comments
Closed

Generate mocks for interfaces with generic types #173

lucastorri opened this issue Apr 6, 2022 · 5 comments

Comments

@lucastorri
Copy link

Hi!

I went through the existing issues and was not sure whether one specific to supporting interfaces with generic types exists. I had a look at #168, but this is about generating mocks for types which package uses generics.

In sum, I would like to have an interface such as:

//go:generate moq -stub -out publisher_mock.go . Publisher

type Publisher[M any] interface {
	Publish(ctx context.Context, msg M)
}

and be able to use a generic mock in my test:

publisher := PublisherMock[Something]{}

publisher.Publish(ctx, Something{})

Thank you!

@fish-sammy
Copy link

Any update here?

@matryer
Copy link
Owner

matryer commented Oct 1, 2022

Moq hasn't been upgraded to support generics yet. We need to do it.

@sudo-suhas
Copy link
Collaborator

@lucastorri can you check if this is still an issue?

@lucastorri
Copy link
Author

Hi @sudo-suhas, I can confirm that it works with the reported case.

In case anyone is interested, here is the generated code:

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

package test

import (
	"context"
	"sync"
)

// Ensure, that PublisherMock does implement Publisher.
// If this is not the case, regenerate this file with moq.
var _ Publisher[any] = &PublisherMock[any]{}

// PublisherMock is a mock implementation of Publisher.
//
//	func TestSomethingThatUsesPublisher(t *testing.T) {
//
//		// make and configure a mocked Publisher
//		mockedPublisher := &PublisherMock{
//			PublishFunc: func(ctx context.Context, msg M)  {
//				panic("mock out the Publish method")
//			},
//		}
//
//		// use mockedPublisher in code that requires Publisher
//		// and then make assertions.
//
//	}
type PublisherMock[M any] struct {
	// PublishFunc mocks the Publish method.
	PublishFunc func(ctx context.Context, msg M)

	// calls tracks calls to the methods.
	calls struct {
		// Publish holds details about calls to the Publish method.
		Publish []struct {
			// Ctx is the ctx argument value.
			Ctx context.Context
			// Msg is the msg argument value.
			Msg M
		}
	}
	lockPublish sync.RWMutex
}

// Publish calls PublishFunc.
func (mock *PublisherMock[M]) Publish(ctx context.Context, msg M) {
	callInfo := struct {
		Ctx context.Context
		Msg M
	}{
		Ctx: ctx,
		Msg: msg,
	}
	mock.lockPublish.Lock()
	mock.calls.Publish = append(mock.calls.Publish, callInfo)
	mock.lockPublish.Unlock()
	if mock.PublishFunc == nil {
		return
	}
	mock.PublishFunc(ctx, msg)
}

// PublishCalls gets all the calls that were made to Publish.
// Check the length with:
//
//	len(mockedPublisher.PublishCalls())
func (mock *PublisherMock[M]) PublishCalls() []struct {
	Ctx context.Context
	Msg M
} {
	var calls []struct {
		Ctx context.Context
		Msg M
	}
	mock.lockPublish.RLock()
	calls = mock.calls.Publish
	mock.lockPublish.RUnlock()
	return calls
}

@lucastorri
Copy link
Author

Thanks all for the support!

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

4 participants