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

Mock.On panics when it expects a func parameter #1179

Open
okmkey45 opened this issue Apr 21, 2022 · 1 comment
Open

Mock.On panics when it expects a func parameter #1179

okmkey45 opened this issue Apr 21, 2022 · 1 comment
Labels
pkg-mock Any issues related to Mock question Questions related to API usage rejected/invalid Not a bug but a misunderstanding by the requester

Comments

@okmkey45
Copy link

Hello, I've been having issues mocking an interface that expects a func as a parameter. Not sure if this is a bug or maybe an opportunity to improve a little bit the docs (And if this is not the place for this, I'm really really sorry. I hope you can redirect me to the right place to ask these questions)

My interface:

type ExcelFileReader interface {
	ForEachRow(
		fileAbsolutePath string,
		sheetName string,
		closure func(row []string) (bool, error), // Here it's where the issue starts
	) error
}

My implementation:

type FileParser struct {
	reader file.ExcelFileReader
}

func (fp FileParser) GetDataPoints(
	path string,
	df DataFile,
) (data []model.DataPoint, err error) {
	if path == "" {
		return data, fmt.Errorf("path cannot be empty")
	}
	if df.IsZero() {
		return data, fmt.Errorf("data file cannot be empty")
	}

	fpath := filepath.Join(path, df.Filename())

	err = fp.reader.ForEachRow(fpath, df.SheetName(), func(row []string) (bool, error) {
		dp, dpErr := parseDataPoint(row)
		if dpErr != nil {
			return false, dpErr
		}

		data = append(data, dp)
		return true, nil
	})

	return data, err
}

My mock:

type MockExcelFileReader struct {
	Mock mock.Mock
}

func (m MockExcelFileReader) ForEachRow(
	fileAbsolutePath string,
	sheetName string,
	closure func(row []string) (bool, error),
) error {
	args := m.Mock.Called(
		fileAbsolutePath,
		sheetName,
		closure,
	)
	return args.Error(0)
}

And inside my test, I have a helper function to create an instance of the mock:

func getTestExcelFileReader(
	testPath string,
	testDataFile DataFile,
	err error,
) mocks.MockExcelFileReader {
	tr := mocks.MockExcelFileReader{}

	tr.Mock.On(
		"ForEachRow",
		fmt.Sprintf("%s/%s", testPath, testDataFile.Filename()),
		testDataFile.SheetName(),
		mock.AnythingOfType("func(row []string) (bool, error)"),
	).Return(err)

	return tr
}

And when I run the test, what I get is:

panic: 

mock: Unexpected Method Call
-----------------------------

ForEachRow(string,string,func([]string) (bool, error))
                0: "some path/some filename"
                1: "some sheet name"
                2: (func([]string) (bool, error))(0x57b640)

The closest call I have is: 

ForEachRow(string,string,mock.AnythingOfTypeArgument)
                0: "some path/some filename"
                1: "some sheet name"
                2: "func(row []string) (bool, error)"


Diff: 0: PASS:  (string=some path/some filename) == (string=some path/some filename)
        1: PASS:  (string=some sheet name) == (string=some sheet name)
        2: FAIL:  type func(row []string) (bool, error) != type  - (func([]string) (bool, error)=0x57b640) [recovered]

My guess is there's a problem when I'm using mock.AnythingOfType("func(row []string) (bool, error)") inside the Mock.On method. And of course, I can't pass an actual func since by doing this, I'll get an exception:

panic: cannot use Func in expectations. Use mock.AnythingOfType("func([]string) (bool, error)")

Please let me know if more info is needed. If there's a problem on how I'm using the mock, then I'd like understand and maybe contribute with a tiny PR adding an example to the docs. I think this could help a few folks. I did some research on line and I found people asks these questions but no clear answer is found

@brackendawson
Copy link
Collaborator

The error message you got suggests this is a known limitation and shows you what you need to do:

panic: cannot use Func in expectations. Use mock.AnythingOfType("func([]string) (bool, error)")

This limitation is unlikely to be addressed as functions cannot be compared in Go, even using reflection.

@dolmen dolmen added pkg-mock Any issues related to Mock question Questions related to API usage rejected/invalid Not a bug but a misunderstanding by the requester labels Jul 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg-mock Any issues related to Mock question Questions related to API usage rejected/invalid Not a bug but a misunderstanding by the requester
Projects
None yet
Development

No branches or pull requests

3 participants