为什么我们使用接口来模拟方法 Golang
Why we use interface for mocking methods Golang
刚接触Golang,一直在摸索,但不太清楚单元测试中的mocking。任何人都可以解释以下具体问题吗?
问题1:在Golang中编写单元测试,为什么我们需要有模拟方法的接口,为什么不只是struct?
问题2: 为什么我们在struct中注入接口(调用外部方法的地方)
使用结构 -
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
}
谢谢
如果你在包用户中有类型的方法,比如说,例如。
包用户
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
使用这种方法 mock 可以在测试 运行 时轻松通过,例如:
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。
问题1:在Golang中编写单元测试,为什么我们需要有模拟方法的接口,为什么不只是struct?
回答:不是强制性的
问题2:为什么要在struct中注入接口(调用外部方法的地方)
回答:因为,它可以帮助您替换实际的函数调用(作为单元测试的一部分可能会触发一些超出范围的操作,例如 数据库调用,some API call etc) 通过注入 MockStruct
(这将实现与实际代码中相同的 interface
)。 多态性 简单来说。
因此,您创建了一个 MockStruct
并为其定义了您自己的 mockMethods
。作为多态性,你的单元测试选择 MockStruct
毫无怨言。调用实际数据库或 http
端点不属于 单元测试 。
仅供参考,我可以向您指出我的 github 代码库之一,我在其中编写了 small test case for a file。如您所见,我嘲笑了 :
GuestCartHandler
interface , that allowed me to not call the actual implementation
- 使用
"github.com/DATA-DOG/go-sqlmock"
包模拟 sql
connection。这帮助我避免建立实际的 db client
(因此,单元测试时不依赖数据库)
如果您从概念上理解了这个想法,或者您是否需要更多说明,请告诉我。
刚接触Golang,一直在摸索,但不太清楚单元测试中的mocking。任何人都可以解释以下具体问题吗?
问题1:在Golang中编写单元测试,为什么我们需要有模拟方法的接口,为什么不只是struct?
问题2: 为什么我们在struct中注入接口(调用外部方法的地方)
使用结构 -
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
}
谢谢
如果你在包用户中有类型的方法,比如说,例如。 包用户
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
使用这种方法 mock 可以在测试 运行 时轻松通过,例如:
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。
问题1:在Golang中编写单元测试,为什么我们需要有模拟方法的接口,为什么不只是struct?
回答:不是强制性的
问题2:为什么要在struct中注入接口(调用外部方法的地方)
回答:因为,它可以帮助您替换实际的函数调用(作为单元测试的一部分可能会触发一些超出范围的操作,例如 数据库调用,some API call etc) 通过注入 MockStruct
(这将实现与实际代码中相同的 interface
)。 多态性 简单来说。
因此,您创建了一个 MockStruct
并为其定义了您自己的 mockMethods
。作为多态性,你的单元测试选择 MockStruct
毫无怨言。调用实际数据库或 http
端点不属于 单元测试 。
仅供参考,我可以向您指出我的 github 代码库之一,我在其中编写了 small test case for a file。如您所见,我嘲笑了 :
GuestCartHandler
interface , that allowed me to not call the actual implementation- 使用
"github.com/DATA-DOG/go-sqlmock"
包模拟sql
connection。这帮助我避免建立实际的db client
(因此,单元测试时不依赖数据库)
如果您从概念上理解了这个想法,或者您是否需要更多说明,请告诉我。