【问题标题】:Golang http handler testing with inner functions使用内部函数测试 Golang http 处理程序
【发布时间】:2021-09-16 11:01:30
【问题描述】:

我想为我的 http 处理程序构建一个测试部分,并且我想按原样使用 http 处理程序函数,但我想有单独的函数来模拟处理的 db 部分。我的想法是这样的:

package main

import (
    "log"
    "testing"
)

// DB functions
type UserDBFunctions interface {
    InsertUser() string
}

type UserDB struct {
}

func (u UserDB) InsertUser() string {
    return "hello"
}

// http handler functions
type UserHandlerFunctions interface {
    Register() string
}

type UserHandler struct {
    userDb *UserDB
}

func newUserHandler() UserHandler {
    return UserHandler{userDb: new(UserDB)}
}

func (u UserHandler) Register() string {
    str := u.userDb.InsertUser()
    return str + " world"
}

func main() {
    var i UserHandlerFunctions = newUserHandler()
    str :=  i.Register()
    log.Println(str)
}

// test functions
type FakeUserDBFunctions interface {
    InsertUser() string
}

type FakeUserDB struct {
}

func (u FakeUserDB) InsertUser() string {
    return "bye"
}

func newFakeUserHandler() UserHandler {
    return UserHandler{userDb: *UserDB(&FakeUserDB{})}
}

func TestRegisterUser(t *testing.T) {
    t.Run("register user", func(t *testing.T) {
        var i UserHandlerFunctions = newFakeUserHandler()
        str := i.Register()
        log.Println(str)
    })
}

所以第一个接口是真正的 db 函数,然后是调用 db 函数的 http 处理程序,在 main() 函数下面应该是带有 db 函数模型的测试。但这部分不起作用。如何用模型替换 newUserHandler 中的真实接口。

非常感谢您的帮助。 ????

【问题讨论】:

  • 我认为你做的有点不对。 IMO 一个更经典的方法是拥有一个接口“用户数据库”,它必须由您的“真实”UserDB 类型和一些在测试中实例化的存根/模拟/假类型来实现。你的其余代码——一个特定的 HTTP 服务器多路复用器或其他任何东西——在构建时提供了一个实现该“用户数据库”接口的类型的实例,并且完全忘记了它所使用的实例的真正动态类型;多路复用器的处理程序——也是。然后,您可以使用处理程序并酌情检查结果。
  • 我无法想象你的结构。我想要一个 userHandler,它有多个处理函数,比如func (u User) RegisterUser(rw ..., r ...) {...},并且 userHandler 结构用一个服务结构初始化,我用它来初始化数据库、AuthMiddleware 等,我可以将它重用于所有服务。现在我已经将数据库逻辑与 http 处理(例如检查值等)分开了。
  • 我想在不使用数据库的情况下测试 http 处理程序。但我只需要 db 部分中的上述服务结构,我想模拟它以进行 http 处理程序测试。这就是为什么我要构建一个新的 FakeUserDB。
  • 这里是一个例子:play.golang.org/p/sgV3sni0BDd

标签: go testing struct interface


【解决方案1】:

UseHandler 应使用 UserDBFunctions 而不是 UserDB。

type UserHandler struct {
    userDb UserDBFunctions
}

这是修改后的https://play.golang.org/p/nLiaomKA2NH

【讨论】:

  • 非常感谢,这很容易解决。我不能感谢你,我无法自己解决它。 ?
  • 如何访问 UserDB 中的另一个结构?在我的示例中它是空的,但在我的真实代码中它不是,我必须调用i.userDb.newStruct...
  • 我不确定我是否理解了这个问题,这就是您要找的吗? play.golang.org/p/myE1H9FtLWo
  • 不完全是,我不需要在 InsertUser 函数中使用 u.storage.StoreData("rec1") ,但我需要在你的示例中调用 u.userDb.storage.StoreData()主要功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多