Mocking system commands

Mocking is a technique to replace parts of a system with interfaces that don’t do anything, but which your tests can check whether and how they were called. The unittest.mock module in Python 3 lets you mock Python functions and classes. These tools let you mock external commands.

Commands are mocked by creating a real file in a temporary directory which is added to the PATH environment variable, not by replacing Python functions. So if you mock foo, and your Python code runs a shell script which calls foo, it will be the mocked command that it runs.

By default, mocked commands record each call made to them, so that your test can check these. Using the MockCommand API, you can mock a command to do something else.

Note

These tools work by changing global state. They’re not safe to use if commands may be called from multiple threads or coroutines.

testpath.assert_calls(cmd, args=None)

Assert that a block of code runs the given command.

If args is passed, also check that it was called at least once with the given arguments (not including the command name).

Use as a context manager, e.g.:

with assert_calls('git'):
    some_function_wrapping_git()
    
with assert_calls('git', ['add', myfile]):
    some_other_function()
class testpath.MockCommand(name, content=None)

Context manager to mock a system command.

The mock command will be written to a directory at the front of $PATH, taking precedence over any existing command with the same name.

By specifying content as a string, you can determine what running the command will do. The default content records each time the command is called and exits: you can access these records with mockcmd.get_calls().

On Windows, the specified content will be run by the Python interpreter in use. On Unix, it should start with a shebang (#!/path/to/interpreter).

get_calls()

Get a list of calls made to this mocked command.

This relies on the default script content, so it will return an empty list if you specified a different content parameter.

For each time the command was run, the list will contain a dictionary with keys argv, env and cwd.