3

I'm writing unit tests for a function that I developed in golang. Here is the code snippet:

func myFunc () {
    //there is some code
    err := json.Unmarshal (a, &b)
    if err != nil {
        //handle error    
    }

    //there is some more code

    err := json.Unmarshal (c, &d)
    if err != nil {
        //handle error    
    }
}

Now I want to mock first unmarshal to return success and second unmarshal to return failure. In python, I see one similar post: Python mock multiple return values

But I cannot find one for golang. Can anyone please help me on this.

  • Unfortunately this is not that simple in Golang. The best bet would be to refactor your function so that `json.Unmarshal` can be forcefully made to return an error, e.g. when calling `json.Unmarshal(a, &b)` and a is not in json format. – Yerken Jun 14 '17 at 23:15

1 Answers1

2

What I would do in this situation is have an exported package variable Unmarshaller and set it to json.Unmarshal in the init() method.

var Unmarshaller func(data []byte, v interface{}) error;

func init() {
    Unmarshaller = json.Unmarshal
}

Then, when you want to force an error, you can just do

mypackage.Unmarshaller = func(data[] byte, v interface{}) error {
    return errors.New("It broke!")
}

Then, in your code, instead of calling json.Unmarshal directly, you call your package level `Unmarshaller, so

err =: json.Unmarshal(jsonBytes, &test)

would become

err =: Unmarshaller(jsonBytes, &test)

As a short example: https://play.golang.org/p/CinLmprtp5

dave
  • 62,300
  • 5
  • 72
  • 93