Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spying on methods in Golang

Is there any way to spy on methods in Golang?

For example, suppose I have

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
}

In writing a test against Object.Something, we should not need to care about what's happening in SomethingElse or the Process invoked from within. Is there any way, in Golang, to isolate these dependencies?

like image 274
Mike Warren Avatar asked Sep 21 '18 15:09

Mike Warren


1 Answers

My understanding of spying is that a single method of an object is faked or mocked while others are not. That's not possible in Go. But you can fake or mock your entire dependencies using interfaces.

In order to fake the SomethingElse method you would have to put it on another struct separate from your Object struct. The Object struct would also need an interface with the SomethingElse method.

type Object struct {
    A     int
    elser Elser
}

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

type Elser interface {
    SomethingElse()
}

Now you can test the Object behavior by creating a fake that implements the SomethingElse method:

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")
    }
}

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

like image 87
dmowzy Avatar answered Sep 30 '22 18:09

dmowzy