Skip to content

Justintime50/mockcmd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mockcmd

Mocks the exec.Command interface in Golang.

Build Status Coverage Status Version Licence

Showcase

Mocking the exec.Command interface in Golang is an absolute pain. You run the risk of running system commands in a unit test context or are required to build out a custom solution to run your commands in an isolated and safe manner which still isn't ideal. Enter mockcmd, the easy and safe way to mock your exec.Command functions.

mockcmd accomplishes a safe and easy mocking of the exec.Command interface by creating a fake cmd function and passing your command and args through to it. We assert that the Stdout gets passed through and returned correctly for success and that an err gets returned in the case of failure.

Install

go get github.com/Justintime50/mockcmd

Usage

Your Command

Below is an example on how to setup your CMD command in a way it can be easily mocked:

package mypackage

import (
    "github.com/Justintime50/mockcmd/mockcmd"
)

// Pass in `exec.Command` as the context for your real command
func main() {
    out, _ := myCommandFunction(exec.Command)
    fmt.Println(out.String())
}

func myCommandFunction(cmdContext mockcmd.ExecContext) (*bytes.Buffer, error) {
    cmd := cmdContext("echo", "Hello World")
    var outb bytes.Buffer
    cmd.Stdout = &outb
    err := cmd.Run()
    if err != nil {
        fmt.Printf("Failed to run command: %s", err)
        return nil, err
    }

    return &outb, nil
}

Your Test

Below is an example on how to setup your test to mock your command from above:

// Mock a success and failure response from exec.Command
func TestMyCommandFunctionSuccess(t *testing.T) {
    stdout, err := myCommandFunction(mockcmd.MockExecSuccess)
    mockcmd.Success(t, stdout, err)
}

func TestMyCommandFunctionFailure(t *testing.T) {
    _, err := myCommandFunction(mockcmd.MockExecFailure)
    mockcmd.Fail(t, err)
}

// The following functions are required in each package that will mock an exec.Command
// Do not alter the following when placed into your package_test.go file
func TestMockProcessSuccess(t *testing.T) {
    if os.Getenv("GO_TEST_PROCESS") != "1" {
        return
    }
    os.Stdout.WriteString("mocked Stdout")
    os.Exit(0)
}

func TestMockProcessFailure(t *testing.T) {
    if os.Getenv("GO_TEST_PROCESS") != "1" {
        return
    }
    os.Exit(1)
}

Development

# Get a comprehensive list of development tools
make help

Attribution