In Pytest, Is there a way to "mock" or prevent something from happening while collecting test?

Question:

So assume the allowing :

# services/foo.py

from apps.bar import BarClass

static_foos = BarClass().get_statics()

class FooService() :
     ....

and test code looking like :

# tests/test_foo.py

from services.foo import FooService

def test_foo_something() :
    assert FooService.something() == True

So here, when the pytest collects the test, it seems like it executes BarClass.get_statics() even before any of my attempts to mock or block access in conftest.py to kick in.

To be more specific, assuming get_statics() has some requests.get in it, a typical way of blocking network in pytest, which is mocking socket.socket, is not working.

From my knowledge, the only way to do something before tests get collected is to use pytest_configure in conftest.py, but also AFAIK it doesn’t allow me to mock meaning that I’m just completely losing hope right now (Also it’s not like I can really change the content of test_something for various reasons).

Is there any possible solution in this case?

Asked By: bmjeon5957

||

Answers:

You can import the services.foo module within the test function instead, after you monkey-patch requests.get:

import requests

# define your MockResponse class here

def test_foo_something(monkeypatch):
    def mock_get(*args, **kwargs):
        return MockResponse()

    monkeypatch.setattr(requests, "get", mock_get)
    from services.foo import FooService

    assert FooService.something() == True
Answered By: blhsing

You can import BarClass from apps.bar right before importing FooService and mock the get_statics. For example:

from apps.bar import BarClass

def do_nothing(*args, **kwargs):
    pass

BarClass.get_statics = do_nothing

from services.foo import FooService

def test_foo_something() :
    assert FooService.something() == True

However I think it would be better to add some initializing function to services.foo and call it when its needed. Something like:

from apps.bar import BarClass

static_foos = None

def init():
    static_foos = BarClass().get_statics()

class FooService():
    ...
Answered By: maciek97x
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.