rawr rang
rawr rang

Reputation: 973

Patching away function call before importing?

If I'm importing from a module and want to prevent a function call from being ran in it, how can achieve that? For example...

sandbox.py

def foo():
    print("doing something I don't want to happen during testing like making a connection")
    ....

x = foo()

def get_num():
    return 1

test_sandbox.py

from sandbox import get_num

def get_num():
    assert get_num() == 1

I don't really care about foo or x, just want a way to make it so foo is not called when test_sandbox.py makes the import up top. In this current state, I will end up running foo.

How do I mock or patch to prevent foo from running during the import?

Upvotes: 0

Views: 524

Answers (1)

gold_cy
gold_cy

Reputation: 14216

You can do this using monkeypatch however, you need to know what foo is calling in order to patch it before importing. Taking your example we can illustrate how this would work.

import io
import sys


def test_get_num(monkeypatch):
    stdout = io.StringIO()

    with monkeypatch.context() as mc:
        mc.setattr(sys, 'stdout', stdout)
        from sandbox import get_num

        assert stdout.getvalue() == "doing something I don't want to happen during testing like making a connection\n"
        assert get_num() == 1

And then when we run it:

$ -> pytest -s test_sandbox.py 
========================= test session starts =========================================
collected 1 item                                                                                                                                                         

test_sandbox.py .

Notice how even running pytest with -s to allow print statements to be shown in the console don't appear. You can do the same with foo in your real world example. If it is creating some database connection, then monkeypatch the connection to do nothing and then import after that. Hope that helps.

Upvotes: 1

Related Questions