stretchr / testify

A toolkit with common assertions and mocks that plays nicely with the standard library
MIT License
23.56k stars 1.6k forks source link

Use function pointers to set up mock expectations #425

Open littledot opened 7 years ago

littledot commented 7 years ago

testify provides the On() function to set up mock expectations, which uses a string to identify the mocked function. However, Go provides an API runtime.FuncForPC() which allows users to obtain a function pointer's name.

type Sap struct {
}

func (i *Sap) Magic() {
    fmt.Println("Magic")
}

func dump(a interface{}) {
    name := runtime.FuncForPC(reflect.ValueOf(a).Pointer()).Name()
    fmt.Println(name)
}

func main() {
    dump((*Sap).Magic) // "main.(*Sap).Magic"
    s := &Sap{}
    dump(s.Magic) // "main.(*Sap).Magic-fm"
    sa := Sap{}
    dump(sa.Magic) // "main.(*Sap).Magic-fm"
}

https://play.golang.org/p/RAB0zOkB0L

What are your thoughts on providing a new API similar to On() which accepts function pointers in the form of interface{} instead of string? The implementation would then parse the function pointer's name to identify the method that needs mocking. I think this could really reduce pains in refactoring code - such as method renaming - because tools can now pick up these tokens.

tartale commented 7 years ago

👍

wuxinwei commented 6 years ago

sounds great, as well as I need a feature to On() receive a function pointer as a parameter

ccoVeille commented 2 years ago

I'm really interested in this. The issue is old. Do you know if anyone implemented it somewhere may be a fork ?

I can try to implement it in few weeks

The current implementation is a bit frustrating for me when I refactor code with my IDE, the string used everywhere are not updated, and I have to manually edit tons of files.

ccoVeille commented 2 years ago

based on a quick code check, I think the code needed to implement it is close to what is currently in (m *Mock) Called

ccoVeille commented 2 years ago

for further reading: https://stackoverflow.com/questions/7052693/how-to-get-the-name-of-a-function-in-go

ccoVeille commented 2 years ago

but I don't plan to work on it, until someone confirms it's not already implemented somewhere

marrow16 commented 1 year ago

@ccoVeille @littledot you might try https://github.com/go-andiamo/mmock

ccoVeille commented 1 year ago

@ccoVeille @littledot you might try https://github.com/go-andiamo/mmock

Thanks. I love it. I will try.

How far is your code from testify? Do you think it could it be integrated in testify via a PR?

I didn't read your code yet. I'm in holidays with only a phone for now.

ccoVeille commented 8 months ago

@marrow16

I also found xgo.Mock very promising

https://github.com/xhd2015/xgo