Go 如何在diff实现中使用函数接口

Go 如何在diff实现中使用函数接口,go,interface,Go,Interface,我在测试中使用接口,我想模拟它其中的一个方法函数1,但我无法弄清楚如何最好地做到这一点,对于产品代码,它将提供1个值,对于测试,它将提供一些模拟值,有人能举个例子吗?(编辑) 代码如下: 测试是这样的 func Test_callSomething(t *testing.T) { type args struct { si vInterface } tests := []struct { name string args

我在测试中使用
接口
,我想模拟它其中的一个方法
函数1
,但我无法弄清楚如何最好地做到这一点,对于产品代码,它将提供1个值,对于测试,它将提供一些模拟值,有人能举个例子吗?(编辑) 代码如下:

测试是这样的

func Test_callSomething(t *testing.T) {
    type args struct {
        si vInterface
    }
    tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "my tests",
            args: args{

            },
            want: false,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := callSomething(tt.args.si); got != tt.want {
                t.Errorf("callSomething() = %v, want %v", got, tt.want)
            }
        })
    }
}
但不知道如何正确地嘲弄它

更新

func Test_mStruct_vl1(t *testing.T) {
    type fields struct {
        info string
        time time.Time
    }
    tests := []struct {
        name   string
        fields fields
        want   bool
    }{
        {
            name: "some test",
            fields: struct {
                info string
                time time.Time
            }{info: "myinfo", time: time.Now() },

        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            s := &mStruct{
                info: tt.fields.info,
                time: tt.fields.time,
            }
            if got := s.vl1(); got != tt.want {
                t.Errorf("vl1() = %v, want %v", got, tt.want)
            }
        })
    }
}
首先,您需要一个实现
vInterface
接口的类型(任意类型)。下面是一个简单的例子:

type mockedVInterface struct {
    value bool
}

func (m mockedVInterface) function1() bool {
    return m.value
}
这是一个我们可以控制的非常简单的实现:我们可以通过简单地将该值设置为它的
字段来判断它的
function1()
函数应该返回什么


mockedVInterface
类型仅为测试目的而创建,生产代码不需要它。将它放在测试代码所在的同一个文件中(将它放在
test\u callSomething()
之前)

下面是测试代码:

func Test_callSomething(t *testing.T) {
    type args struct {
        si vInterface
    }
    tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "testing false",
            args: args{
                si: mockedVInterface{value: false},
            },
            want: false,
        },
        {
            name: "testing true",
            args: args{
                si: mockedVInterface{value: true},
            },
            want: true,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := callSomething(tt.args.si); got != tt.want {
                t.Errorf("callSomething() = %v, want %v", got, tt.want)
            }
        })
    }
}
注意,在这个简单的例子中,我们也可以使用一个简单的非结构类型,它的底层类型是
bool
,如下所示:

type mockedVInterface bool

func (m mockedVInterface) function1() bool {
    return bool(m)
}
它可以工作,测试代码也更简单:

tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "testing false",
            args: args{
                si: mockedVInterface(false),
            },
            want: false,
        },
        {
            name: "testing true",
            args: args{
                si: mockedVInterface(true),
            },
            want: true,
        },
    }

但是,只有当mockable接口有一个函数和一个返回值时,这才有效。在一般情况下,需要一个结构。

不清楚要做什么。你想嘲笑什么
msstruct.function1()
在代码中返回
true
。你想让它在测试过程中返回
false
?@icza-我想用
function1
的不同实现测试函数
callSomething
,有时是true,有时是false谢谢,对不起什么是
mockedVInterface
,我应该把它放在测试的什么地方?如果是,您能提供完整的代码吗?
mockedVInterface
是一种仅为测试目的而创建的新类型。你可以简单地把它放在你有
test\u callSomething()。您不能在函数中定义方法。谢谢,1+,您能解释一下为什么使用模拟接口而不是模拟函数吗?
tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "testing false",
            args: args{
                si: mockedVInterface(false),
            },
            want: false,
        },
        {
            name: "testing true",
            args: args{
                si: mockedVInterface(true),
            },
            want: true,
        },
    }