golang中的模拟内部函数

1 dependency-injection interface go

我想使用接口来模拟函数,并且我能够模拟第一个函数callsomething\n在 的大力帮助下icza,现在\xe2\x80\x99s 有点棘手。我想测试函数vl1\n使用模拟函数 function1,它是如何完成的。

\n\n

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

\n\n

包主

\n\n
import (\n    "fmt"\n    "time"\n    "testing"\n)\n\ntype vInterface interface {\n    function1() bool\n}\n\ntype mStruct struct {\n    info string\n    time time.Time\n}\n\nfunc (s *mStruct) function1() bool {\n    return true\n}\n\nfunc callSomething(si vInterface) bool {\n    return si.function1()\n}\n\nfunc (s *mStruct) vl1() bool {\n    return callSomething(s)\n}\n\nvar currentVt1 mStruct\n\nfunc main() {\n    vl1 := currentVt1.vl1()\n\n    fmt.Println(vl1)\n}\n\n//\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94TESTS\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\n\n// This test is working as expected (as suggested by icza) for the function  "callSomething"\n// here we use mock interface and mock function which helps to mock function1\ntype mockedVInterface struct {\n    value bool\n}\n\nfunc (m mockedVInterface) fn1() bool {\n    return m.value\n}\n\nfunc Test_callSomething(t *testing.T) {\n\n\n\n    type args struct {\n        si vInterface\n    }\n    tests := []struct {\n        name string\n        args args\n        want bool\n    }{\n        {\n            name: "first value",\n            args: args{\n                si: mockedVInterface{value: false},\n            },\n            want: false,\n        },\n        {\n            name: "second value",\n            args: args{\n                si: mockedVInterface{value: true},\n            },\n            want: true,\n        },\n    }\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            if got := callSomething(tt.args.si); got != tt.want {\n                t.Errorf("callSomething() = %v, want %v", got, tt.want)\n            }\n        })\n    }\n}\n\n\n\n//----Here is the test which a bit tricky \n//I want to call to "s.vl1()" and test it with mock for "function1"\n\nfunc Test_mStruct_vl1(t *testing.T) {\n    type fields struct {\n        info string\n        time time.Time\n    }\n    tests := []struct {\n        name   string\n        fields fields\n        want   bool\n    }{\n        {\n            name: "test 2",\n            fields: struct {\n                info string\n                time time.Time\n            }{info: "myinfo", time: time.Now() },\n\n        },\n    }\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            s := &mStruct{\n                info: tt.fields.info,\n                time: tt.fields.time,\n            }\n            //here the test is starting\n            if got := s.vl1(); got != tt.want {\n                t.Errorf("mStruct.vl1() = %v, want %v", got, tt.want)\n            }\n        })\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

mko*_*iva 5

如果你想在 Go 中模拟一个函数,你必须声明一个变量来保存函数值,让该函数的所有调用者都使用该变量,然后在测试期间你可以切换模拟实现的函数值。

func callSomethingFunc(si vInterface) bool {
    return si.function1()
}

var callSomething = callSomethingFunc

func (s *mStruct) vl1() bool {
    return callSomething(s)
}

// ...

func Test_mStruct_vl1(t *testing.T) {
    callSomething = func(si vInterface) bool { // set mock
        // do mock stuff
    }
    defer func(){
        callSomething = callSomethingFunc // set back original func at end of test
    }()
    // ...
Run Code Online (Sandbox Code Playgroud)