Search code examples
unit-testingtestinggomocking

Is it possible to mock a function imported from a package?


I have the following method to test, which uses a function imported from a package.

import x.y.z

func abc() {
    ...
    v := z.SomeFunc()
    ... 
}

Is it possible to mock SomeFunc() in Go?


Solution

  • Yes, with a simple refactoring. Create a zSomeFunc variable of function type, initialized with z.SomeFunc, and have your package call that instead of z.SomeFunc():

    var zSomeFunc = z.SomeFunc
    
    func abc() {
        // ...
        v := zSomeFunc()
        // ...
    }
    

    In tests you may assign another function to zSomeFunc, one that is defined in tests, and does whatever the test wants it to.

    For example:

    func TestAbc(t *testing.T) {
        // Save current function and restore at the end:
        old := zSomeFunc
        defer func() { zSomeFunc = old }()
    
        zSomeFunc = func() int {
            // This will be called, do whatever you want to,
            // return whatever you want to
            return 1
        }
    
        // Call the tested function
        abc()
    
        // Check expected behavior
    }
    

    See related / possible duplicate: Testing os.Exit scenarios in Go with coverage information (coveralls.io/Goveralls)