如何在 Golang 中只模拟特定方法

Ale*_*rio 13 unit-testing overriding interface go

我对 golang 还很陌生,我正在为一项简单的任务而苦苦挣扎。

我在 golang 有以下课程

type struct A {
}

func (s *A) GetFirst() {
    s.getSecond()
}

func (s *A) getSecond() {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

我想为它编写一些测试,但是我需要覆盖getSecond(). 我试图在我的测试文件中执行以下操作

type Ai interface {
    getSecond()
}

type testA struct {
    A
}

func (s *testA) getSecond() {
     // do nothing
}

func TestA(t *testing.T) {
   a := &A{}
   t := &testA{A: a}
   t.GetFirst()  
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是将 AgetSecond()方法公开给接口并通过使用嵌入来覆盖,但这似乎不起作用。测试仍然调用原始实现getSecond()而不是我的模拟实现。

一个解决方案当然是为 A 创建一个适当的接口,其中包含getFirst()getSecond()然后在测试中创建一个结构,实现 wheregetFirst()调用原始实现和getSecond()虚拟,但是我觉得这很麻烦,而不是正确的做事方式。

另一种可能性是getSecond()在实际实现中分配给一个变量并在测试中覆盖该变量,但我也觉得仅仅为了一个简单的覆盖而这样做有点奇怪。

我在这件事上做错了吗?有没有更简单的方法可以使用 golang 做到这一点?

Ben*_*ish 11

根据此答案,您无法真正覆盖 golang 中的方法。但是,正如您指出的那样,您可以为“getSecond 方法”使用一个单独的接口,并在您的测试用例中使用一个实现,在您的实际代码中使用一个实现。

type s interface{ 
    getSecond()
}

type A struct{
    s
}

type a struct{

}

func (s *A) GetFirst() {
    s.getSecond()
}

func (s a) getSecond() {
    // do something
}

//Use a 
A{a{}}
Run Code Online (Sandbox Code Playgroud)

然后在测试中有一个不同的“a”实现

type ta struct {

}
func (s ta) getSecond() {
    // do nothing
}

A{ta{}}
Run Code Online (Sandbox Code Playgroud)

  • 如果您想在“getSecond”中模拟“getThird”函数,这个解决方案就会变得很麻烦! (3认同)