Mike Warren
Mike Warren

Reputation: 3866

Stubbing a function in Golang

There's a function that keeps coming up in the code that I'm responsible for unit-testing (that hasn't even been tested yet), defined as follows:

//Get Retreives an error with the given access code.
func Get(code AccessCode) *ErrorSt {
    if err, ok := Errors[code]; ok {
        err.Stack = utilityCore.GetCleanStack(logger.Instance.GetProjectNames())
        return &err
    }
    err := NewError(string(ACPanic), fmt.Sprintf("Error '%s' can't be retreived.", code), ESSystem, SError)
    return err
}

It is invoked by a couple of the methods that I have tried to test thus far. My instinct is to either stub or spy on the function, but this fails.

This function is used in many places throughout my employer's APIs, thus I cannot change it (if I do, it will break a lot of things). Is there any way to do true unit testing and test-double it out?

My spy attempt:

type ErrorSpy struct {
    spies.Spy
}

func (spy *ErrorSpy) Get(code AccessCode) *ErrorSt {
    res := spy.Called(code)

    return res.Get(0).(*ErrorSt)
}

Upvotes: 2

Views: 1520

Answers (1)

Mike Warren
Mike Warren

Reputation: 3866

Learned that spying is only doable on methods implemented from interfaces (I'm so used to Java, where everything is method!) I talked to the boss, and he said no to the proposal of refactoring this function, and all the instances in which it's used, to a method.

Failing that, I had to break the core principle of unit-testing and worry about what Get was returning. Luckily, in my case, it was trying to return an ErrorSt from the map Errors. Seeing that, I had to simply do the following:

errors := Errors
Errors = map[AccessCode]ErrorSt { 
    // anything I expect Get to return 
}

defer func() { Errors = errors }()

and then I was good to go.

Upvotes: 2

Related Questions