What's the best way to mock a dependency in GO when the dependency doesn't expose an interface

huangapple go评论155阅读模式
英文:

What's the best way to mock a dependency in GO when the dependency doesn't expose an interface

问题

我正在尝试模拟https://gopkg.in/olivere/elastic.v2,但事实证明这是一场噩梦。我通常使用gomock,但由于该依赖没有接口文件,所以我无法使用。有什么最好的方法可以解决这个问题?

英文:

Im trying to mock https://gopkg.in/olivere/elastic.v2 and its proven to be a nightmare. I usually use gomock but I can't because theres no interface file for the dep. What's the best way to go about this?

答案1

得分: 5

创建你自己的接口。

它甚至不需要完整,只需要覆盖你实际使用的方法。

假设你有一个类型为 Foo 的结构体,具有以下方法:Bar()Baz()Qux()

你在代码中使用它:

func Frobnicate(f *Foo) err {
    if err := f.Bar() error; err != nil {
        return err
    }
    return nil
}

只需更改为使用你自己的自定义接口:

type barer interface() {
    Bar() error
}

然后更新函数签名:

func Frobnicate(f fooer) err {
    // 其余部分与之前相同

现在创建你自己的 fooer 实现,并进行模拟。

如果你需要模拟的类型是一个简单的带有数据的结构体,而不是带有方法的结构体,你可以使用 getter/setter 方法包装该方法,以便接口可以使用它。例如,给定以下类型:

type Foo struct {
    Name string
}

你可以创建一个包装器:

type FooWrapper struct {
    Foo
}

func (w *FooWrapper) Name() string {
    return w.Foo.Name
}

现在可以使用自定义接口来访问 Foo 类型以进行模拟。

英文:

Create your own interface.

It doesn't even need to be complete, either, it only needs to cover the methods you actually use.

Suppose you have a type Foo with the following methods: Bar(), Baz(), and Qux().

And you use this in your code:

func Frobnicate(f *Foo) err {
    if err := f.Bar() error; err != nil {
        return err
    }
    return nil
}

Just change this to use your new custom interface:

type barer interface() {
    Bar() error
}

Then update your function signature:

func Frobnicate(f fooer) err {
    // The rest the same as before

Now create your own fooer implementation, and mock away.

If the type you need to mock is a simple struct with data, instead of with methods, you may wrap the method with getter/setter methods, so that an interface will work around it. Example, given this type:

type Foo struct {
    Name string
}

You can create a wrapper:

type FooWrapper struct {
    Foo
}

func (w *FooWrapper) Name() string {
    return w.Foo.Name
}

Now the Foo type can be accessed using a custom interface for mocking.

huangapple
  • 本文由 发表于 2017年4月22日 03:38:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/43550727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定