Patch scripts called by Snakemake for testing

I am writing tests for snakemake and I am wondering if it is possible to mock some of the functions in the scripts I’m calling from Snakemake. My setup looks like this

# Snakemake file

rule call_api:
    input:
       input.txt
    output:
       output.txt
    shell:
       "run_script.py"
# run_script.py

def make_call_to_api():
    pass

def main():
    response = make_call_to_api()
    # do other things
    # save things to output

if __name__ == __main__:
    main()

I want to patch make_call_api so I can run tests without actually calling the API with something like this:

# test.py
import subprocess
from unittest.mock import patch


@patch("runscript.make_call_to_api")
def test_snakemake(mock_api):
    mock_api.return_value= 200
    subprocess.run(['snakemake', '-c', '1', '--Snakefile', 'Snakefile', '--use-singularity])
    assert some_output == expected_output

While I can patch the function if I am calling it from outside I can’t mock it when it’s Snakemake calling it. When invoked from snakemake, the function is not patched at all and it will try to make a call to the API. I am fairly certain it is “mock objects where they are used, not where they are defined” problem, but where are they defined in Snakemake? Of course, I can try to set up an environment and run the test from that environment without Snakemake, but Snakemake makes managing env so easy that it would be nice if I could call the script from Snakemake but with a patched function. I am fairly sure it is a

Leave a Comment