cmdexec

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2024 License: GPL-3.0 Imports: 10 Imported by: 4

README

cmdexec

Latest Version License GitHub Workflow Status Codecov

Go library for mocking exec.Command and exec.CommandContext calls. Aims to provide an as close as possible [exec.Cmd]-like interface for drop-in support.

Differences

  • Instead of setting cmd.Stdin (or in/err), use SetStdin() functions instead. This is due to those being fields on a struct, which cannot be on an interface.

Usage

See our Go docs.

Asserting Output

Normally, you shouldn't need to assert anything as your function that executes a command should give you testing signal (is it working or not 😉). However, you can assert certain fields with this library. Currently, this is limited to Stdin checking.

If you set [MockCommand.Stdin] and call SetStdin in the function executing a command, Stdin will be checked to ensure it is equal. This is to allow greater testing if required.

License

GPL-3.0

Documentation

Overview

Package cmdexec provides a way to execute commands using the exec package while supporting mocking for testing purposes. The default behaviour of the package is to simply wrap exec.Command and it's context accepting counterpart, exec.CommandContext. However, when running in tests, the package can be configured to use a mock executor that allows for controlling the output and behaviour of the commands executed for testing purposes.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func UseMockExecutor

func UseMockExecutor(t mockt.T, mock *MockExecutor)

UseMockExecutor replaces the executor used by cmdexec with a mock executor that can be used to control the output of all commands created after this function is called. A cleanup function is added to the test to ensure that the original executor is restored after the test has finished.

Note: This function can only ever be called once per test. If called again in the same test, it will cause the test to fail.

Usage:

func TestSomething(t *testing.T) {
    mock := cmdexec.NewMockExecutor()
    mock.AddCommand(&cmdexec.MockCommand{
        Name:   "echo",
        Args:   []string{"hello", "world"},
        Stdout: []byte("hello world\n"),
    })

    cmdexec.UseMockExecutor(t, mock)

    // Your test code here.
}

Types

type Cmd

type Cmd interface {
	// Output matches [exec.Cmd.Output].
	Output() ([]byte, error)
	// CombinedOutput matches [exec.Cmd.CombinedOutput].
	CombinedOutput() ([]byte, error)
	// Run matches [exec.Cmd.Run].
	Run() error
	// String returns the command line string that will be executed.
	String() string

	// SetEnviron sets the environment variables of the command. Matches
	// the behavior of setting [exec.Cmd.Environ] directly.
	SetEnviron([]string)

	// SetDir sets the working directory of the command.
	SetDir(string)

	// SetStdout, SetStderr, and SetStdin set the stdout, stderr, and
	// stdin of the command respectively.
	SetStdout(io.Writer)
	SetStderr(io.Writer)
	SetStdin(io.Reader)

	// UseOSStreams sets Stdout, Stderr, and Stdin to the OS streams
	// (os.Stdout, os.Stderr, and os.Stdin respectively). If stdin is
	// false then Stdin is not set.
	UseOSStreams(stdin bool)
}

Cmd is an interface to be used instead of exec.Cmd for mocking purposes.

func Command

func Command(name string, arg ...string) Cmd

Command returns a new Cmd that will call the given command with the given arguments. See exec.Command for more information.

func CommandContext

func CommandContext(ctx context.Context, name string, arg ...string) Cmd

CommandContext returns a new Cmd that will call the given command with the given arguments and the given context. See exec.CommandContext for more information.

type MockCommand

type MockCommand struct {
	// Name is the name (or path) of the command that should be called to
	// trigger this mock.
	Name string

	// Args is the pair of arguments that the command should be called
	// with to trigger this mock.
	Args []string

	// Stdout is the expected output that the command should write to
	// stdout.
	Stdout []byte

	// Stderr is the expected output that the command should write to
	// stderr.
	Stderr []byte

	// Stdin is the expected input that the command should read from
	// stdin. If this is set, the command will check that the provided
	// stdin matches the expected input. SetStdin() must be called to set
	// the actual stdin data.
	Stdin []byte

	// Err is an error that will be returned when the command is executed.
	// If not set, the command will return nil.
	Err error
	// contains filtered or unexported fields
}

MockCommand is a command that can be executed by the MockExecutor.

func (*MockCommand) CombinedOutput

func (c *MockCommand) CombinedOutput() ([]byte, error)

CombinedOutput implements the Cmd interface, see [Cmd.CombinedOutput] for more information.

func (*MockCommand) Output

func (c *MockCommand) Output() ([]byte, error)

Output implements the Cmd interface, see [Cmd.Output] for more information.

func (*MockCommand) Run

func (c *MockCommand) Run() error

Run implements the Cmd interface, see [Cmd.Run] for more information.

func (*MockCommand) SetDir added in v1.1.0

func (c *MockCommand) SetDir(_ string)

SetDir implements the Cmd interface. For the MockCommand, this is a no-op because we do not actually execute any commands.

func (*MockCommand) SetEnviron added in v1.1.0

func (c *MockCommand) SetEnviron(_ []string)

SetEnviron implements the Cmd interface. For the MockCommand, this is a no-op because we do not actually execute any commands.

func (*MockCommand) SetStderr

func (c *MockCommand) SetStderr(_ io.Writer)

SetStderr implements the Cmd interface. For the MockCommand, this is a no-op because we do not actually execute any commands.

func (*MockCommand) SetStdin

func (c *MockCommand) SetStdin(r io.Reader)

SetStdin sets the stdin of the command to the given reader. This is used for validation purposes to ensure that the provided stdin matches what was expected.

func (*MockCommand) SetStdout

func (c *MockCommand) SetStdout(_ io.Writer)

SetStdout implements the Cmd interface. For the MockCommand, this is a no-op because we do not actually execute any commands.

func (*MockCommand) String added in v1.1.0

func (c *MockCommand) String() string

String implements the Cmd interface, see [Cmd.String] for more information.

func (*MockCommand) UseOSStreams

func (c *MockCommand) UseOSStreams(_ bool)

UseOSStreams implements the Cmd interface. For the MockCommand, this is a no-op because we do not actually execute any commands.

type MockExecutor

type MockExecutor struct {
	// contains filtered or unexported fields
}

MockExecutor provides an executor that returns mock data.

func NewMockExecutor

func NewMockExecutor(cmds ...*MockCommand) *MockExecutor

NewMockExecutor returns a new MockExecutor with the given commands. A MockExecutor contains various commands that should be mocked instead of actually executed.

Once a MockExecutor is created and used with UseMockExecutor, it will error if any commands are executed that were not registered with the executor.

Commands that have had SetStdin() called and set Stdin data will also have their stdin checked to ensure that the provided input matches the expected input, this enables testing of commands that read from stdin.

func (*MockExecutor) AddCommand

func (e *MockExecutor) AddCommand(cmd *MockCommand)

AddCommand adds a command to the executor. If the command has already been added, it will be replaced.

Note: This is not thread-safe.

Directories

Path Synopsis
internal
mockt
mockt implements a system for mocking testing.T.
mockt implements a system for mocking testing.T.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL