为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我们使用接口来模拟 Golang 方法

为什么我们使用接口来模拟 Golang 方法

Go
慕娘9325324 2022-06-21 16:59:33
我是 Golang 的新手,一直在探索但不清楚单元测试中的模拟。谁能解释以下具体问题?问题1:在 Golang 中编写单元测试,为什么我们需要有接口来模拟方法,为什么不只有 struct ?问题2:为什么我们在结构中注入接口(我们称之为外部方法)使用结构 -type GlobalData struct {}var (    GlobalObj = GlobalData{})func (g GlobalData) GetGlobalData(a string) string{    return a}带有接口定义-type GlobalInterface interface {    GetGlobalData(a string) string}type GlobalData struct {}var (    GlobalObj = GlobalData{})func (g GlobalData) GetGlobalData(a string) string{    return a}谢谢
查看完整描述

2 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

问题 1:为了在 Golang 中编写单元测试,为什么我们需要模拟方法的接口,为什么不只是 struct ?

答:不是强制性的

问题 2:为什么我们在 struct 中注入接口(我们调用外部方法)

回答:因为,它可以帮助您通过注入MockStruct(实现interface与是否存在于实际代码中)。简单的多态性

所以,你创建一个MockStruct并定义你自己mockMethods的。作为多态性,您的单元测试选择MockStruct没有抱怨。调用实际的数据库或http端点不属于单元测试

仅供参考,我可以将您指向我的一个 github 代码库,在那里我为一个文件编写了一个小测试用例。如您所见,我嘲笑:

  1. GuestCartHandlerinterface,这使我可以不调用实际的实现

  2. 使用包模拟sql连接。"github.com/DATA-DOG/go-sqlmock"这帮助我避免建立实际db client的(因此,在单元测试时不依赖数据库)

如果您从概念上理解这个想法,或者您是否需要更多说明,请告诉我。


查看完整回答
反对 回复 2022-06-21
?
湖上湖

TA贡献2003条经验 获得超2个赞

如果你有关于包用户类型的方法,比如说,ex。包用户


type User struct {

 name string

}


func (u *User) GetUserProfile() UserProfile{}

现在在目录包中导入:


package catalog


import user


func getUserCatalog(user user.User) []catalog {

 user.GetUserProfile()

}

现在测试 getUserCatalog 方法有两种方法:


1. var getUserProfileFunc = user.GetUserProfile

使用这种方法模拟可以在测试运行时轻松通过,例如:


getUserProfile = func() UserProfile { 

 return fakeUserProfile 

}

这是测试它的最简单方法。


现在还有另一种使用接口的方法,在包用户中添加一个接口,如


type UserInterface interface {

  GetUserProfile() UserProfile

}

如果用户包是您无法控制的库,则创建自己的界面,键入并使用它。


在这种情况下,目录包中的测试将变为:


因为现在方法将从 UserInterface 类型而不是从 UserType 调用,因此在测试时:


UserInterface = fakeUserStruct

并按照以下步骤


//1. define type of func to return 


type typeGetUserProfile func() UserProfile


//2. create a var to return


var mockedGetUserProfile typeGetUserProfile


//3. create a type


type FakeUser struct{}


//4. implement method interface


func (user *FakeUserStruct) GetUserProfile() UserProfile{

  return mockedGetUserProfile

 }

现在运行测试时:


mockerGetUserProfile = func() UserProfile {

  return fakeUserProfile

 }

有一个模拟库可以帮助创建用于模拟的样板代码。检查这个https://github.com/stretchr/testify


还有很多其他的模拟库,但我用过这个,这真的很酷。


我希望这有帮助。


如果没有请告诉我,我会给出一些示例代码并将其推送到 Github。


另请检查https://levelup.gitconnected.com/utilizing-the-power-of-interfaces-when-mocking-and-testing-external-apis-in-golang-1178b0db5a32


查看完整回答
反对 回复 2022-06-21
  • 2 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号