Go 如何在被测函数内部创建模拟
我有一组函数,它们使用对象池。这个游泳池已经被嘲笑了。它在大多数情况下都能正常工作。但在某些函数中,我从池中调用对象的方法。所以我也需要模拟这些对象 让我们说:Go 如何在被测函数内部创建模拟,go,testing,mocking,Go,Testing,Mocking,我有一组函数,它们使用对象池。这个游泳池已经被嘲笑了。它在大多数情况下都能正常工作。但在某些函数中,我从池中调用对象的方法。所以我也需要模拟这些对象 让我们说: // ObjectGeter is a interface that is mocked type ObjectGeter interface { GetObject(id int) ObjectType, error } // this function is under test func SomeFunc(og Obj
// ObjectGeter is a interface that is mocked
type ObjectGeter interface {
GetObject(id int) ObjectType, error
}
// this function is under test
func SomeFunc(og ObjectGeter,id int, otherArgument SomeType) error {
// some actions with otherArgument
// and may be return an error
obj, err := og.GetObject(id)
if err !=nil {
return errors.New("GetObject error")
}
rezult, err := obj.SomeMethod()
if err !=nil {
return errors.New("One of internal errors")
}
return rezult, nil
}
有没有办法测试整个功能?我可以创建接口SomeMethoder,该接口封装了SomeMethod(),但是我找不到如何在SomeFunc内部将其分配给obj,而不将GetObject的签名更改为GetObject(id int)SomeMethoder,错误
目前,我看到了一种方法——通过部件进行测试。我发现的唯一不改变范例的解决方案是包装器。这是相当琐碎,但可能有人会需要它一次 最初我有一些类型:
type PoolType struct {...}
func (p *PoolType)GetObject(id int) (ObjectType, error) {...}
还有一个接口,它包装了PoolType.GetObject,我对它进行了模拟
现在我有了界面:
type SomeMethoder interface {
SomeMethod() (ResultType, error)
}
type ObjectGeter interface {
GetObject(id int) (SomeMethoder, error)
}
包装由PoolType.GetObject()返回的对象
要生成它,我有接口:
type SomeMethoder interface {
SomeMethod() (ResultType, error)
}
type ObjectGeter interface {
GetObject(id int) (SomeMethoder, error)
}
和类型
type MyObjectGeter struct {
pool *PoolType
}
func New(pool *PoolType) *MyObjectGeter {
return &MyObjectGeter{pool: pool}
}
func (p *MyObjectGeter)GetObject(id int) (SomeMethoder, error) {
return p.pool.GetObject(id)
}
这就实现了它
因此:
被称为
og := New(pool)
SomeFunc(og,id,otherArgument)
在实际工作中
毕竟,要测试整个函数,我必须:
func TestSomeFuncSuccess (t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
objectGeter := mocks.NewMockObjectGeter(controller)
someMethoder := mocks.NewMockSomeMethoder(controller)
gomock.InOrder(
args.objectGeter.EXPECT().
GetObject(correctIdCOnst).
Return(someMethoder, nil),
args.someMethoder.EXPECT().
SomeMethod().
Return(NewResultType(...),nil).
Times(args.test.times[1]),
)
result, err := SomeFunc(objectGeter,correctIdCOnst,otherArgumentConst)
// some checks
}
因此,唯一未测试的部分是MyObjectGeter.GetObject,这对我来说已经足够了。如果希望
GetObject
返回可模拟的实例,则必须更改签名。然而,您应该重新考虑是否真的需要一个mock来测试该功能,也许ObjectGetter mock可以返回一个ObjectType的实例,该实例在不引入另一个mock的情况下很容易测试。主要的问题完全源于mock。停止嘲笑其他语言推广它的方式。您已经有了一个ObjectGeter接口,为了测试您必须提供的一些乐趣和ObjectGeter是否正常工作:它必须提供对象,而这些对象必须有一些方法。与其尝试注入模拟僵尸,不如提供具有适当、已知、一致和可测试状态的适当对象。不要嘲笑。写赝品或存根。