Go 如何在接口内模拟特定的嵌入式方法
我有这段代码,我想写一个更新函数的单元测试 如何模拟Go 如何在接口内模拟特定的嵌入式方法,go,Go,我有这段代码,我想写一个更新函数的单元测试 如何模拟FindByUsername函数 我试图覆盖u.FindByUsername,但它不起作用 此外,我可以编写一些函数,将u*UserLogic和userName string作为输入参数,并执行u.FindByUsername()并模拟此函数,但这不是一个干净的解决方案,我需要一个更好的解决方案来模拟UserOperation接口中的方法 package logic import ( "errors" "fmt" ) var
FindByUsername
函数
我试图覆盖u.FindByUsername
,但它不起作用
此外,我可以编写一些函数,将u*UserLogic
和userName string
作为输入参数,并执行u.FindByUsername()
并模拟此函数,但这不是一个干净的解决方案,我需要一个更好的解决方案来模拟UserOperation
接口中的方法
package logic
import (
"errors"
"fmt"
)
var (
dataStore = map[string]*User{
"optic": &User{
Username: "bla",
Password: "ola",
},
}
)
//UserOperation interface
type UserOperation interface {
Update(info *User) error
FindByUsername(userName string) (*User, error)
}
//User struct
type User struct {
Username string
Password string
}
//UserLogic struct
type UserLogic struct {
UserOperation
}
//NewUser struct
func NewUser() UserOperation {
return &UserLogic{}
}
//Update method
func (u *UserLogic) Update(info *User) error {
userInfo, err := u.FindByUsername(info.Username)
if err != nil {
return err
}
fmt.Println(userInfo.Username, userInfo.Password)
fmt.Println("do some update logic !!!")
return nil
}
//FindByUsername method
func (u *UserLogic) FindByUsername(userName string) (*User, error) {
userInfo := &User{}
var exist bool
if userInfo, exist = dataStore[userName]; !exist {
return nil, errors.New("user not found")
}
return userInfo, nil
}
更新
我尝试用这段代码模拟函数
func TestUpdate2(t *testing.T) {
var MockFunc = func(userName string) (*User, error) {
return &User{Username:"foo", Password:"bar"},nil
}
user := NewUser()
user.FindByUsername = MockFunc
user.Update(&User{Username:"optic", Password:"ola"})
}
您在
UserOperation
界面中混合了两个抽象级别:Update
取决于FindByUsername
。要使Update
可测试,您需要将UserFinder
功能注入Update
方法。您可以这样做,例如通过在UserLogic
struct中定义一个字段:
type UserOperation interface {
Update(info *User) error
}
type UserFinder func(userName string) (*User, error)
type UserLogic struct {
UserOperation
FindByUsername UserFinder
}
//NewUser struct
func NewUser() *UserLogic { // return structs, accept interfaces!
return &UserLogic{
findByUsername: FindByUsername
}
}
func (u *UserLogic) Update(info *User) error {
userInfo, err := u.findByUsername(info.Username)
if err != nil {
return err
}
fmt.Println(userInfo.Username, userInfo.Password)
fmt.Println("do some update logic !!!")
return nil
}
func FindByUsername(userName string) (*User, error) {
userInfo := &User{}
var exist bool
if userInfo, exist = dataStore[userName]; !exist {
return nil, errors.New("user not found")
}
return userInfo, nil
}
您在
UserOperation
界面中混合了两个抽象级别:Update
取决于FindByUsername
。要使Update
可测试,您需要将UserFinder
功能注入Update
方法。您可以这样做,例如通过在UserLogic
struct中定义一个字段:
type UserOperation interface {
Update(info *User) error
}
type UserFinder func(userName string) (*User, error)
type UserLogic struct {
UserOperation
FindByUsername UserFinder
}
//NewUser struct
func NewUser() *UserLogic { // return structs, accept interfaces!
return &UserLogic{
findByUsername: FindByUsername
}
}
func (u *UserLogic) Update(info *User) error {
userInfo, err := u.findByUsername(info.Username)
if err != nil {
return err
}
fmt.Println(userInfo.Username, userInfo.Password)
fmt.Println("do some update logic !!!")
return nil
}
func FindByUsername(userName string) (*User, error) {
userInfo := &User{}
var exist bool
if userInfo, exist = dataStore[userName]; !exist {
return nil, errors.New("user not found")
}
return userInfo, nil
}
您想模拟该函数以便测试更新吗?你试过什么不起作用的?是的,我试着模仿``func TestUpdate(t*testing.t){var MockFunc=func(用户名字符串)(*User,error){return&User{userName:“foo”,Password:“bar”},nil}User:=NewUser()User.FindByUsername=MockFunc User.Update(&User{userName:“optic”,Password:“ola”})```但它不起作用。请不要在注释中添加代码,而是更新您的问题。不能将函数分配给Go中的方法。您可以编写接口
UserOperation
的模拟实现,并在测试过程中使用它。@请看一看:尽管这不是真正的模拟,但我将其称为假或存根,mock通常允许您指定希望调用的方法及其参数和返回值,然后在测试结束时检查它们是否实际被调用。您可能想尝试一下:您想模拟该函数以便测试更新吗?你试过什么不起作用的?是的,我试着模仿``func TestUpdate(t*testing.t){var MockFunc=func(用户名字符串)(*User,error){return&User{userName:“foo”,Password:“bar”},nil}User:=NewUser()User.FindByUsername=MockFunc User.Update(&User{userName:“optic”,Password:“ola”})```但它不起作用。请不要在注释中添加代码,而是更新您的问题。不能将函数分配给Go中的方法。您可以编写接口UserOperation
的模拟实现,并在测试过程中使用它。@请看一看:尽管这不是真正的模拟,但我将其称为假或存根,mock通常允许您指定希望调用的方法及其参数和返回值,然后在测试结束时检查它们是否实际被调用。您可能想尝试一下: