agiledragon / gomonkey

gomonkey is a library to make monkey patching in unit tests easy
MIT License
2k stars 179 forks source link

v2-dsl: "panic: patch has been existed [recovered]" #37

Open PanZ12580 opened 3 years ago

PanZ12580 commented 3 years ago

Can't mock repeat? Here is my demo function to be mocked:

func FuncDo(str string) (string, error) {
    if err := ToBeMock(str); err != nil {
        return "", err
    }
    return fmt.Sprintf("hello, %s", str), nil
}

func ToBeMock(str string) error {
    return nil
}

And then I write my test unit:

func TestFuncDo(t *testing.T) {
    patches := gomonkey.NewPatches()
    defer patches.Reset()
    patchesBuilder := dsl.NewPatchBuilder(patches)

    // the 1st way
    /*patchesBuilder.Func(ToBeMock).
        Stubs().
        With(dsl.Any()).
        Will(dsl.Return(nil)).
        Then(dsl.Repeat(dsl.Return(fmt.Errorf("error")), 1)).
        End()*/

    tests := []struct{
        name string
        mock func()
        wantErr bool
    } {
        {
            name: "success",
            mock: func() {

                // the 2nd way
                patchesBuilder.Func(ToBeMock).
                    Stubs().
                    With(dsl.Any()).
                    Will(dsl.Repeat(dsl.Return(nil), 1)).
                    End()
            },
            wantErr: false,
        },
        {
            name: "error",
            mock: func() {
                patchesBuilder.Func(ToBeMock).
                    Stubs().
                    With(dsl.Any()).
                    Will(dsl.Return(fmt.Errorf("error"))).
                    End()
            },
            wantErr: true,
        },
    }

    for _, obj := range tests {
        obj.mock()
        t.Logf("===RUN\tTestDo3/%s", obj.name)
        _, err := FuncDo("str")
        if (err != nil) != obj.wantErr {
            t.Errorf("wantErr %v, actual: %v", obj.wantErr, err)
        }
    }
}

but no matter I use the first way or the second way, I can't achieve the expected results(with 1st way, the result setted in "Then" don't take effect, and with 2nd way, it will throw a painc: panic: patch has been existed

how can I use v2 to get the expected results?