Skip to content

Instantly share code, notes, and snippets.

@earonesty
Last active January 18, 2022 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earonesty/2fbb42b7a34e5acbbcd26caca529bb8c to your computer and use it in GitHub Desktop.
Save earonesty/2fbb42b7a34e5acbbcd26caca529bb8c to your computer and use it in GitHub Desktop.
# allows you to say with mock_run(...):
# ....
# good for testing scripts that do a lot of subprocess.run calls
class CmdMatch(NamedTuple):
cmd: str
matches: str = ".*"
result: str = ""
side_effect: Union[Callable, Exception] = None
@contextlib.contextmanager
def mock_run(*cmd_match: Union[str, CmdMatch], **kws):
sub_run = subprocess.run
mock = MagicMock()
if isinstance(cmd_match[0], str):
cmd_match = [CmdMatch(*cmd_match, **kws)]
def new_run(cmd, **_kws):
check_cmd = " ".join(cmd[1:])
mock(*cmd[1:])
for m in cmd_match:
if m.cmd in cmd[0].lower() and re.match(m.matches, check_cmd):
if m.side_effect:
if isinstance(m.side_effect, Exception):
raise m.side_effect
m.side_effect()
return subprocess.CompletedProcess(cmd, 0, m.result, "")
assert False, "No matching call for %s" % check_cmd
subprocess.run = new_run
yield mock
subprocess.run = sub_run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment