如何在 golang 中测试映射对象

我尝试在我的 go 代码中实现一些单元测试,发现模拟方法的主题非常困难。我有以下示例,希望您能帮助我 :)


在第一层我有以下代码:


package api


import (

    "fmt"

    "core"

)


type createUserDTO struct {

    Id string

}


func ApiMethod() {

    fmt.Println("some incoming api call wit user")

    incomingUserData := &createUserDTO{Id: "testId"}

    mapedUser := incomingUserData.mapUser()

    mapedUser.Create()

}


func (createUserDTO *createUserDTO) mapUser() core.User {

    return &core.UserCore{Id: createUserDTO.Id}

}

第二层有如下代码:


package core


import (

    "fmt"

)


type CoreUser struct{ Id string }


type User interface {

    Create()

}


func (user CoreUser) Create() {

    fmt.Println("Do Stuff")

}

我现在的问题是,如何在不测试核心包的情况下测试 api 包中的每个公共方法。特别是方法 Create()。


胡子哥哥
浏览 99回答 1
1回答

胡说叔叔

根据评论,我整理了一个简单的 GitHub 存储库来展示我通常如何处理 Go 中的结构化项目。存储库暂时不考虑测试部分,但使用此项目结构插入它们应该很容易。让我们从一般文件夹的布局开始:controllersservicesdbdtomodels现在,让我们看看相关文件。models/user.gopackage modelsimport "gorm.io/gorm"type User struct {    *gorm.Model    Id string `gorm:"primaryKey"`}func NewUser(id string) *User {    return &User{Id: id}}简单的结构定义在这里。dto/user.gopackage dtoimport "time"type UserDTO struct {    Id      string    `json:"id"`    AddedOn time.Time `json:"added_on"`}func NewUserDTO(id string) *UserDTO {    return &UserDTO{Id: id}}我们用一个虚拟字段来丰富模型结构,AddedOn这只是为了演示。db/user.gopackage dbimport (    "gorm.io/gorm"    "userapp/models")type UserDb struct {    Conn *gorm.DB}type UserDbInterface interface {    SaveUser(user *models.User) error}func (u *UserDb) SaveUser(user *models.User) error {    if dbTrn := u.Conn.Create(user); dbTrn.Error != nil {        return dbTrn.Error    }    return nil}在这里,我们定义了一个使用User存储库的接口。在我们的测试中,我们可以提供模拟而不是UserDb结构的实例。services/user.gopackage servicesimport (    "time"    "userapp/db"    "userapp/dto"    "userapp/models")type UserService struct {    DB db.UserDbInterface}type UserServiceInterface interface {    AddUser(inputReq *dto.UserDTO) (*dto.UserDTO, error)}func NewUserService(db db.UserDbInterface) *UserService {    return &UserService{        DB: db,    }}func (u *UserService) AddUser(inputReq *dto.UserDTO) (*dto.UserDTO, error) {    // here you can write complex logic    user := models.NewUser(inputReq.Id)    // invoke db repo    if err := u.DB.SaveUser(user); err != nil {        return nil, err    }    inputReq.AddedOn = time.Now()    return inputReq, nil}这是桥接表示层和底层存储库之间连接的层。controllers/user.gopackage controllersimport (    "encoding/json"    "io"    "net/http"    "userapp/dto"    "userapp/services")type UserController struct {    US services.UserServiceInterface}func NewUserController(userService services.UserServiceInterface) *UserController {    return &UserController{        US: userService,    }}func (u *UserController) Save(w http.ResponseWriter, r *http.Request) {    reqBody, err := io.ReadAll(r.Body)    if err != nil {        panic(err)    }    r.Body.Close()    var userReq dto.UserDTO    json.Unmarshal(reqBody, &userReq)    userRes, err := u.US.AddUser(&userReq)    if err != nil {        w.WriteHeader(http.StatusInternalServerError)        json.NewEncoder(w).Encode(err)        return    }    w.WriteHeader(http.StatusCreated)    json.NewEncoder(w).Encode(userRes)}在这里,我们定义了(通过依赖注入)使用UserService结构的控制器。您可以在我的GitHub存储库中找到所有内容 如果它能澄清一点,请告诉我。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go