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

unnecessary mock for type definition of func #716

Open
1 of 5 tasks
FLAGLORD opened this issue Sep 27, 2023 · 7 comments
Open
1 of 5 tasks

unnecessary mock for type definition of func #716

FLAGLORD opened this issue Sep 27, 2023 · 7 comments

Comments

@FLAGLORD
Copy link

FLAGLORD commented Sep 27, 2023

Description

When using the designing pattern of Option Pattern, there will be some code below:

// unexported option
type fooOptions struct{
  // some fields
  // ...
}

// Exported function type
type FooOption func(opt *fooOptions)

mockery will produce code below:

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

// Execute provides a mock function with given fields: opt
func (_m *FooOption) Execute(opt *common.fooOptions) {
	_m.Called(opt)
}

// NewFooOption creates a new instance of FooOption. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewFooOption(t interface {
	mock.TestingT
	Cleanup(func())
}) *FooOption {
	mock := &FooOption{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}

It import a unexported struct. Is it a expected behavior? IMO, mockery should not produce a mock for fooOptions as it is not a interface.

Mockery Version

v2.34.0

Golang Version

1.20

Installation Method

  • Binary Distribution
  • Docker
  • brew
  • go install
  • Other: [specify]

Steps to Reproduce

  1. [First Step]
  2. [Second Step]
  3. [etc]

Expected Behavior

[what you expect to happen]

Actual Behavior

[what actually happened]

@LandonTClipp
Copy link
Contributor

Mockery can mock plain functions. What's your config? I wouldn't say this is unexpected.

@FLAGLORD
Copy link
Author

FLAGLORD commented Oct 7, 2023

Thanks for your reply. This is my config:

with-expecter: false
all: true
filename: "{{.InterfaceNameSnake}}.go"
outpkg: mock{{.PackageName}}
mockname: "{{.InterfaceName}}"
dir: test/mock/{{trimPrefix .InterfaceDirRelative "pkg/"}}
packages:
  packageNameA:
    config:
      recursive: true

Is there any way to skip mock for plain functions?

@Foxprodev
Copy link

Foxprodev commented Oct 24, 2023

+1
It generates not working code for me and the only way to skip is enumerate each type name in exclude-regex

@LandonTClipp
Copy link
Contributor

LandonTClipp commented Oct 24, 2023

Semantically speaking, mockery is doing the correct thing as functions are capable of being mocked. However the issue is the use of an unexported struct as you mentioned. From mockery's perspective, this is expected behavior in the sense that you're asking it to generate mocks outside of the original package for a function that uses an unexported struct, which won't compile, but it's what you asked it to do.

The way to fix this in my opinion is either:

  • Add a parameter to skip mocking functions
  • Make mockery skip generating mocks that contain unexported types if the mock doesn't live in the original package (probably my favorite solution because it moves towards mockery rejecting config that is asking for uncompilable code).
  • exclude it using exclude-regex as was mentioned

The first point should probably be added anyway, but it's a bandaid for this particular problem. The second point is the most generalizable. The third already works now but it's manually intensive. The issue is not specific to function types, you would run into the same problem if your interface referenced unexported types.

@Foxprodev
Copy link

Foxprodev commented Oct 24, 2023

Add a parameter to skip mocking functions

Maybe option to filter type signature would be more flexible. Like func.* to filter func types and interface{}|any to filter anonymous interface types or even interfaces containing something interface{.*SomeType.*}

@kilianc
Copy link

kilianc commented Dec 11, 2023

Mockery can mock plain functions.

where do I find this in the docs?

@LandonTClipp
Copy link
Contributor

LandonTClipp commented Dec 14, 2023

where do I find this in the docs?

https://vektra.github.io/mockery/latest/examples/#function-type-case

This is feature was made shortly after I took over the project but I feel like it was an unnecessary addition, and it doesn't seem like it was ever a widely-used feature anyway. While mockery can support this, I encourage people not to and instead just create your own function implementations.

The old pre-packages config semantics natively support function mocking but I never made an attempt to make it work for packages, and if it does work (like what this issue appears to be showing), then it was by accident.

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