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

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

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()

你在代码中使用它:

  1. func Frobnicate(f *Foo) err {
  2. if err := f.Bar() error; err != nil {
  3. return err
  4. }
  5. return nil
  6. }

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

  1. type barer interface() {
  2. Bar() error
  3. }

然后更新函数签名:

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

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

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

  1. type Foo struct {
  2. Name string
  3. }

你可以创建一个包装器:

  1. type FooWrapper struct {
  2. Foo
  3. }
  4. func (w *FooWrapper) Name() string {
  5. return w.Foo.Name
  6. }

现在可以使用自定义接口来访问 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:

  1. func Frobnicate(f *Foo) err {
  2. if err := f.Bar() error; err != nil {
  3. return err
  4. }
  5. return nil
  6. }

Just change this to use your new custom interface:

  1. type barer interface() {
  2. Bar() error
  3. }

Then update your function signature:

  1. func Frobnicate(f fooer) err {
  2. // 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:

  1. type Foo struct {
  2. Name string
  3. }

You can create a wrapper:

  1. type FooWrapper struct {
  2. Foo
  3. }
  4. func (w *FooWrapper) Name() string {
  5. return w.Foo.Name
  6. }

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:

确定