亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 golang 中測試映射對象

如何在 golang 中測試映射對象

Go
胡子哥哥 2023-03-15 14:41:21
我嘗試在我的 go 代碼中實現一些單元測試,發現模擬方法的主題非常困難。我有以下示例,希望您能幫助我 :)在第一層我有以下代碼:package apiimport (    "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 coreimport (    "fmt")type CoreUser struct{ Id string }type User interface {    Create()}func (user CoreUser) Create() {    fmt.Println("Do Stuff")}我現在的問題是,如何在不測試核心包的情況下測試 api 包中的每個公共方法。特別是方法 Create()。
查看完整描述

1 回答

?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

根據評論,我整理了一個簡單的 GitHub 存儲庫來展示我通常如何處理 Go 中的結構化項目。存儲庫暫時不考慮測試部分,但使用此項目結構插入它們應該很容易。
讓我們從一般文件夾的布局開始:

  • controllers

  • services

  • db

  • dto

  • models

現在,讓我們看看相關文件。

models/user.go

package models


import "gorm.io/gorm"


type User struct {

    *gorm.Model

    Id string `gorm:"primaryKey"`

}


func NewUser(id string) *User {

    return &User{Id: id}

}

簡單的結構定義在這里。


dto/user.go

package dto


import "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.go

package db


import (

    "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.go

package services


import (

    "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.go

package controllers


import (

    "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存儲庫中找到所有內容 如果它能澄清一點,請告訴我。



查看完整回答
反對 回復 2023-03-15
  • 1 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號