gpt4 book ai didi

在 Golang 中测试/模拟 3rd 方包

转载 作者:IT王子 更新时间:2023-10-29 01:38:41 25 4
gpt4 key购买 nike

我是 Golang 的新手,在学习这门语言时一直采用 TDD 方法。我一直相处得很好,但我发现测试第三方包非常笨拙,这让我相信我一直在采取错误的方法。

我遇到麻烦的具体情况是模拟 Redis client用于错误处理。我采用的方法是创建我自己的接口(interface),实现包装我想使用的客户端方法。

type Redis interface {
Get(key string) (string, error)
}

type RedisClient struct {
client *redis.Client
}

func (redisClient *RedisClient) New(client *redis.Client) *RedisClient {
redisClient.client = client

return redisClient
}

func (redisClient *RedisClient) Get(key string) (string, error) {
return redisClient.client.Get(key).Result()
}

然后我可以创建一个 mock,它实现相同的接口(interface)以返回我指定的任何值,特别是用于测试错误处理。

我遇到了一个障碍,客户端上的特定方法到 perform transactions (MULTI) 返回属于该包的另一个接口(interface)。在这种情况下我会怎么做?自己实现该接口(interface)似乎是不可能的。

同样,随着此客户端使用量的增长,我自己的实现可能会增长到实现 Redis 的整个接口(interface)的程度 - 这似乎与将其委托(delegate)给外部依赖项的整个想法背道而驰。

有没有更好的方法来测试像这样的第三方包,例如错误处理?

最佳答案

一种方法是创建一个类型,重点关注您想要完成的任务,而不是您正在使用的客户端方法。

假设您只需要一个存储空间来保存和获取用户,您可以想象这样一个界面:

type UserStore interface {
SaveUser(*User) error
GetUserByID(id string) (*User, error)
SearchUsers(query string) ([]User, error)
}

然后您可以实现此存储的 Redis 版本并在其中调用您想要的任何客户端方法,这并不重要。您甚至可以在 PostgreSQL 或其他任何语言中实现一个。此外,使用这种方法进行模拟更容易,因为您需要做的就是实现此接口(interface)而不是 Redis 接口(interface)。

这是该接口(interface)的模拟版本示例:

type UserStoreMock struct {
SaveUserFn func (*User) error
SaveUserInvoked bool
...
}

func (m *UserStoreMock) SaveUser(u *User) error {
m.SaveUserInvoked = true

if m.SaveUserFn != nil {
return m.SaveUserFn(u)
}

return nil
}
...

然后您可以像这样在测试中使用这个模拟:

var m UserStoreMock

m.SaveUserFn = func(u *User) error {
if u.ID != "123" {
t.Fail("Bad ID")
}

return ErrDuplicateError
}
...

关于在 Golang 中测试/模拟 3rd 方包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43724264/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com