监视 Golang 中的方法

Mik*_*ren 5 unit-testing mocking go spy

有没有办法窥探 Golang 中的方法?

例如,假设我有

type Object struct { 
    A int
    B string
    C *interface{}
}   

func (o *Object) Something(val interface{}) {
    o.A = 102
    // some other business logic under test

    o.SomethingElse(o.C, val)
}

//...

func (o *Object) Process(val interface{}) interface{} { 
    // some business logic

    return 43 // or something else. no me importa ya
}

//...

func (o *Object) SomethingElse(iPtr *interface{}, val interface{}) { 

    processedVal := o.Process(val)
    if iPtr == nil { 
        iPtr = new(interface{})
    }

    *iPtr = val
}
Run Code Online (Sandbox Code Playgroud)

在针对 编写测试时Object.Something,我们不需要关心正在发生的事情SomethingElseProcess从内部调用的内容。在 Golang 中,有什么办法可以隔离这些依赖项吗?

dmo*_*wzy 8

我对间谍活动的理解是,对象的单个方法被伪造或嘲笑,而其他方法则不然。这在 Go 中是不可能的。但是您可以使用接口来伪造或模拟整个依赖项。

为了伪造该SomethingElse方法,您必须将其放在与您的Object结构分开的另一个结构上。该Object结构还需要一个与该SomethingElse方法的接口。

type Object struct {
    A     int
    elser Elser
}

func (o *Object) Something() {
    // o.A = 102
    o.elser.SomethingElse()
}

type Elser interface {
    SomethingElse()
}
Run Code Online (Sandbox Code Playgroud)

Object现在您可以通过创建一个实现该方法的假冒来测试该行为SomethingElse

type fakeElser struct {
    somethingElseWasCalled bool
}

func (f *fakeElser) SomethingElse() {
    f.somethingElseWasCalled = true
}

func TestSomething(t *testing.T) {
    fake := &fakeElser{}
    o := &Object{
        elser: fake,
    }
    o.Something()

    if o.A != 102 {
        t.Errorf("expected A to be %d", 102)
    }

    if !fake.somethingElseWasCalled {
        t.Error("expected SomethingElse to be called")
    }
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/RdmbM6Sj5qU