Very Simple Function Mocking with PyTest

Apparently TDD is the way to to modern software development. I say that facetiously, TDD is the ONLY way to do software development!! However, I often find that writing the tests end up taking way more work and is way more complicated than writing the code itself, but mostly that's because I am a newbie to PyTest and unit testing in general.

So today I've been writing a little test for a decorator that determines whether a particular route is allowed or not via a feature switch stored in Redis. Now obviously I need to isolate the decorator function from all the other stuff like the Redis cache and some other bits about permissions. The easy way to do this is to monkeypatch those functions. I've done this SO many times, and every time I forget how to do it, hence this post.

So the very basic mocking I did to replace the get_feature_switches is as follows:

First, create a copy of the return you'd expect from Redis, in this case it's just a list of switches. I want then all to be off so in my case it's just this:

feature_switches_all_off = []

Genius, right?

Then the actual test:

    @pytest.mark.parametrize(
"url, feature_switches, expected_outcome",
[
("/pretend/url/one/", feature_switches_all_off, 418),
("/pretend/url/two/", feature_switches_all_off, 418),
]
)


def test_page_active_decorator_off(self, monkeypatch, url, feature_switches, expected_outcome):

def mock_feature_switches(school_object):
return feature_switches_all_off

monkeypatch.setattr(FeatureSwitchManager, 'get_feature_switches', mock_feature_switches)

response = app.test_client.get(url)
print(response.status_code)
assert response.status_code == expected_outcome

So I'm using PyTest monkeypatch to replace get_feature_switches with my very simple mock_feature_switches function.

Literally the simplest thing ever, and now I will never forget :)

For more PyTest information, this resource has been invaluable to me. We also have his book in the office, thanks Brian!