bytedance / mockey

a simple and easy-to-use golang mock library
Apache License 2.0
556 stars 22 forks source link

Add annotation and example of the mockfunctions #31

Closed healthjyk closed 8 months ago

healthjyk commented 11 months ago

I'm trying to use this repo to take instead of monkey. But there is no annotation and example, so I have to take a lot of time to read the code. Can you add some annotations and examples? Here are the puzzles occurred to me: 1, for MockBuilder, what's the difference of To and Return? For a function of a struct, how do I write the function in To? 2, Do I have to unpatch the MockBuilder after finishing building and using it?

Sychorius commented 11 months ago

We are planning to rewrite README recently for current version is outdated. Here are answers for your question:

  1. To will replace your mock target to the hook function, and Return will directly return the expected value, for example:
    
    func TestXXX(t *testing.T) {
    mockey.PatchConvey("xxx", t, func() {
        fn := func(_ string) bool {
            fmt.Println("fn")
            return false
        }
        mockey.PatchConvey("return", func() {
            mockey.Mock(fn).Return(true).Build()
            fmt.Println(fn("123"))
        })
        mockey.PatchConvey("to", func() {
            var origin = fn
            mockey.Mock(fn).To(func(str string) bool {
                fmt.Println("to called")
                return origin(str)
            }).Origin(&origin).Build()
            fmt.Println(fn("123"))
        })
    })

}

2.  If you are Mocking in `PatchConvey`, you don't need to unpatch it, for example:
```go
func TestXXX(t *testing.T) {
    fn := func() string { return "outer" }
    mockey.PatchConvey("level1", t, func() {
        mockey.Mock(fn).Return("level1").Build()
        mockey.PatchConvey("level2", func() {
            mockey.Mock(fn).Return("level2").Build()
            println(fn()) // level2
        }) //release level2
        println(fn()) // level1
    }) //release level1
    println(fn()) // outer
}

func TestYYY(t *testing.T) {
    fn := func() string { return "outer" }
    convey.Convey("yyy", t, func() {
        println(fn())                                            // outer
        defer mockey.Mock(fn).Return("outer2").Build().UnPatch() // you need to un-patch mocker here
        println(fn())                                            // outer2
    })
}
healthjyk commented 11 months ago

@Sychorius Thanks to your reply. Rewriting README is cool, I'm looking forward to it. For the answers, I have some questions: 1, I want to use To to mock a function belong to a struct, what should I do? The function is kind like this below:

type Hello struct {
    world string
}

func (h *Hello) World() string {
    return h.world
}

How can I mock function Hello.World? 2, When I should use unpatch? Does it mean that I should use it when I only use pkg testing?

Sychorius commented 11 months ago

@healthjyk You can mock struct's method like this:

type Hello struct {
    world string
}

func (h *Hello) World() string {
    return h.world
}

func (h Hello) World2() string {
    return h.world
}
func TestXXX(t *testing.T) {
    mockey.PatchConvey("hello", t, func() {
        mockey.PatchConvey("direct", func() {
            mockey.Mock((*Hello).World).To(func() string {
                return "dlrow"
            }).Build()
            mockey.Mock((Hello).World2 /*no '*' here*/).To(func(self Hello /*optional caller param*/) string {
                return "2dlrow"
            }).Build()
            hello := &Hello{"earth"}
            println(hello.World())
            println(hello.World2())
        })
        mockey.PatchConvey("use GetMethod", func() {
            obj := Hello{}
            mockey.Mock(mockey.GetMethod(obj, "World")).Return("- dlrow").Build()
            mockey.Mock(mockey.GetMethod(obj, "World2")).Return("- 2dlrow").Build()
            hello := &Hello{"earth"}
            println(hello.World())
            println(hello.World2())
        })
    })
}

We recommend writing codes inside PatchConvey. If you do not want to do that, you need to decide where and when to un-patch your mocks by your self. It depends on what your testing code wants to do.