go - 你如何在 Golang 中模拟一个类型中的一个类型?

标签 go mocking

包'gopkg.in/redis.v3'包含一些代码

type Client struct {
}

func (*client) Eval (string, []string, []string) *Cmd {
}

type Cmd struct {
}

func (*Cmd) Result () (interface{}, error) {
}

通过以下方式成功运行

func myFunc (cli *redis.Client) {
    result, err := cli.Eval('my script').Result()
}

问题是有时候Redis集群被锤了,有片刻,结果返回的接口(interface)是nil。

这相当容易处理,但我希望进行测试以确保实际处理它并且不会发生类型断言 panic 。

传统上,我会在 myFunc 中插入一个模拟的 Redis 客户端,它最终可以返回 nil。

type redisClient interface {
    Eval(string, []string, []string) redisCmd
}

type redisCmd interface {
    Result() (interface{}, error)
}

func myFunc (cli redisClient) {
    result, err := cli.Eval('my script').Result()
}

我面临的问题是编译器无法识别 redis.Client 满足接口(interface) redisClient,因为它无法识别从 Eval 返回的 redis.Cmd 满足 redisCmd。

> cannot use client (type *redis.Client) as type redisClient in argument to myFunc:
>    *redis.Client does not implement redisClient (wrong type for Eval method)
>          have Eval(sting, []string, []string) *redis.Cmd
>          want Eval(sting, []string, []string) redisCmd

最佳答案

问题是你的接口(interface)和redis客户端不匹配。如果将界面更改为:

type redisClient interface {
    Eval(string, []string, []string) *redis.Cmd
}

它会编译。话虽这么说,看起来你真的想要 rediscmd,所以你需要围绕 redis 客户端做一个包装器:

type wrapper struct{
  c *redis.Client
}

func (w wrapper) Eval(x sting, y []string, z []string) redisCmd {
  return w.c.Eval(x,y,z) // This assumes that *redis.Cmd implements rediscmd
}

关于go - 你如何在 Golang 中模拟一个类型中的一个类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53823871/

相关文章:

c - C 中的函数模拟?

ruby - Rspec:模拟嵌套/依赖注入(inject)对象

go - 如何获取与 WaitGroup 关联的 goroutines 的数量?

Android - 让 Activity 使用服务模拟

go - 隐式私有(private)函数导入?

go - 在不同类型的结构之间复制公共(public)字段

c++ - 模拟系统调用 - 有更好的方法吗?

unit-testing - 测试基于时间的字段是否有意义? (戈朗)

go - TCPConn Write 在套接字关闭或换行符写入之前什么都不做

html - 使用fmt.Fprintf()发送文本/纯文本