testify icon indicating copy to clipboard operation
testify copied to clipboard

[doc] Document that func (*Call) Return can accept functions

Open KrzysztofMadejski opened this issue 6 years ago • 3 comments

Functions that computes mock return arguments based on input arguments.

Example: mocking a io.Write function:

mf := mocks.RemoteFile{}
mf.On("Close").Return(tt.sftpErrorFileClose)
mf.On("Write", mock.AnythingOfType("[]uint8")).Return(
	func(input []byte) int { return len(input)}, 
	tt.sftpErrorFileWrite)

KrzysztofMadejski avatar Sep 11 '19 08:09 KrzysztofMadejski

Given that functions are first-class citizens in Go and a feature of the language, I would think that's implied. I'm not sure this needs documentation given it's a way the language works?

boyan-soubachov avatar Mar 11 '20 20:03 boyan-soubachov

Your case would make sense if passed function was returned as value. But it is invoked with called mock input arguments and only its return value is returned from mock. Definitely sth to document.

KrzysztofMadejski avatar Mar 11 '20 21:03 KrzysztofMadejski

It seems that this behavior has changed. If you try it now, you'll see that the mock returns the function, not the result of calling the function.

package main

import (
	"testing"

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

type mockGreeter struct {
	mock.Mock
}

func (m *mockGreeter) Greet(name string) string {
	args := m.Called(name)
	return args.String(0)
}

func TestThing(t *testing.T) {
	thing := new(mockGreeter)
	thing.On("Greet", mock.Anything).Return(func(name string) string { return "Hello " + name })
	assert.Equal(t, "Hello User1", thing.Greet("User1"))
	thing.AssertExpectations(t)
}
=== RUN   TestThing
--- FAIL: TestThing (0.00s)
panic: assert: arguments: String(0) failed because object wasn't correct type: %!s(func(string) string=0x104e97f10) [recovered]
	panic: assert: arguments: String(0) failed because object wasn't correct type: %!s(func(string) string=0x104e97f10)

I really wish there was a way to return the result of a function call, but I don't see how to do it with the current API.

mrog avatar Apr 18 '25 15:04 mrog

@mrog that discussion is #350.

brackendawson avatar Sep 16 '25 08:09 brackendawson

There is indeed no need to document this.

brackendawson avatar Sep 16 '25 08:09 brackendawson