【问题标题】:Can I mock out library code with a nested interface? [duplicate]我可以用嵌套接口模拟库代码吗? [复制]
【发布时间】:2020-01-20 15:17:06
【问题描述】:

我试图在我的 go 代码的测试中模拟第 3 方库。但我无法编译我采用的方法。如果我想模拟T2.M2 的结果,有什么方法可以使这项工作,或者我可以采取其他方法吗?

package main

import (
    "fmt"
)

// Two types in a library that I dont have control over
type T1 struct {}
func (T1) M1() T2 {
    return T2{}
}
type T2 struct {}
func (T2) M2() {
    fmt.Println("hello world")
}

// I created these interfaces in order to assign an instance of T1 
// to a variable of type I1 so that I can mock the behavior of T2.M2()
// problem is that this doesn't compile.
type I1 interface {
    M1() I2
}
type I2 interface {
    M2() // I want to mock this method
}

// Then I would be able to create a mock
type Mock1 struct {}
func (Mock1) M1() I2 {
    return Mock2{}
}
type Mock2 struct {}
func (Mock2) M2() {
    fmt.Println("HELLO WORLD")
}

func main() {
    var i1 I1
    i1 = T1{}
    i1.M1().M2()
    i1 = Mock1{}
    i1.M1().M2()
}

https://play.golang.org/p/sv-Uuuke1dr

【问题讨论】:

  • 你不能模拟 T2.M2() 除非你正在模拟的上下文通过接口使用它。如果上下文将其用作结构,那么您最好的选择是填写 T2{} 的模拟实例。
  • 所以没有办法做作业var i1 I1 = T1{}?
  • 否,因为T1 不满足I1 中的约定(T1.M1I1.M1 的签名不匹配)。
  • 我会仔细看看这个库自己的测试是如何编写的;通常,经过良好测试的库也会使使用它的代码易于测试。如果库没有经过良好测试,我会寻找替代方案 - 不仅因为您的测试会很困难,而且因为使用没有经过良好测试的库是一个高风险的提议。

标签: unit-testing go testing interface


【解决方案1】:

将你的依赖包装在嵌入依赖类型的结构中:

// answer wrap your dependency
type Ta1 struct {
  T1
}
func (Ta1) M1() I2 {
    return Ta2{}
}
type Ta2 struct {
   T2
}

然后就可以了:

func main() {
    var i1 I1
    i1 = Ta1{}
    i1.M1().M2()
    i1 = Mock1{}
    i1.M1().M2()
}

试试https://play.golang.org/p/aHr78dY_c9a

【讨论】:

  • 这仅在您的测试使用 Ta1 和 Ta2 或接口 I1 和 I2 时才有效。如果将这些新类型传递给使用 T1 和 T2 的库函数,它将不起作用。
  • @bserdar 我同意。但是如果你模拟这个库并引入你自己的接口,那么就不会有代码直接使用 T1 和 T2。但如果某些消费者需要struct T1,那么我认为没有任何解决方案。 Accept interfaces 他们说。
【解决方案2】:

你不能在 Go 中模拟结构。只有接口。

【讨论】:

  • 这就是为什么第一步是创建一个模仿依赖(或其中一部分)的接口。
猜你喜欢
  • 1970-01-01
  • 2013-09-29
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
相关资源
最近更新 更多