lundi 1 février 2016

go: stub method that outputs result in its input parameter

In the past few days I have been trying to solve a problem, and I understand that I don't have enough insight to do so.

Intro

I have wrapped a json.NewDecoder(r).Decode(v) in a struct that looks like this

t := new(validTransport)
v := make([]foo, 0)
t.Decode(r, &v)

and now v holds all the foos that are read from r.

Problem

My problem is how do I stub the values that will be set to v when I try to unit test something that has a dependency to validTransport.

In my attempt to fix this I have defined a interface Transport on which my functionallity will depend.

type Transport interface{
  Decode(r io.Reader, v interface{})
}

In the unit test I define a fakeTransport and pass it instead of the real implementation. The problem is how do I stub what values will be set to v when Decode gets called.

My not working solution

I have been using testify in order to mock my dependencies that provides a quite nice api to do so.

Code sample:

type fakeTransport struct{
   mock.Mock
   stubValue interface{}
}

func (f *fakeTransport) Decode(r io.Reader, v interface{}){
   f.Called(r,v)  // assert that this function has been called
   want := reflect.ValueOf(f.stubValue)
   reflect.ValueOf(v).Set(want) //stub my value here
}

Question

So my question is how exactly should I deal with methods with such signature that they have their return value actually be one of the input parameters.

If the signature was something like:

type Transport interface{
   Decode(r io.Reader) interface{}
}

then i will just have my stubbed value returned (but that would also enforce the need to do a type assertion which I don't want).

Aucun commentaire:

Enregistrer un commentaire