我正在使用interface
,我想在测试中{strong}模拟其中一种方法function1
,但我无法弄清楚如何做到最好对于prod代码,它将提供1值,而对于test提供一些模拟值,有人可以举例吗? (编辑)
这是代码:
https://play.golang.org/p/w367IOjADFV
package main
import (
"fmt"
"time"
)
type vInterface interface {
function1() bool
}
type mStruct struct {
info string
time time.Time
}
func (s *mStruct) function1() bool {
return true
}
func callSomething(si vInterface) bool {
return si.function1()
}
func (s *mStruct) vl1() bool {
s.time = time.Now()
s.info = "vl1->info"
return callSomething(s)
}
var currentVt1 mStruct
func main() {
vl1 := currentVt1.vl1()
fmt.Println(vl1)
}
测试就是这样
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)
}
})
}
}
答案 0 :(得分:1)
首先,您需要一个实现vInterface
接口的类型(任何类型)。这是一个简单的示例:
type mockedVInterface struct {
value bool
}
func (m mockedVInterface) function1() bool {
return m.value
}
这是一个我们可以控制的足够简单的实现:只需将其值设置为其function1()
字段即可知道其value
函数应该返回什么。
此mockedVInterface
类型仅用于测试目的,生产代码不需要它。将其放在您具有测试代码的文件中(放在Test_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,
},
}
但这仅在可模拟接口具有单个函数且具有单个返回值的情况下有效。通常情况下,需要一个结构。