I have a global variable used as a singleton for hardware access:
in
a.py
:
class _A():
def __init__():
# init hardware here
...
def __del__():
# close hardware connection
a = _A()
Obviously, I don't want my hardware initialized during testing, so I want to mock a, or _A before _A.init() is ever called.
I've tried monkeypatching it using a fixture:
@pytest.fixture
def init_A(monkeypatch):
monkeypatch.setattr('a._A.__init__', Mock())
def test_a(init_A):
import a
#patch a and use it here
Unfortunately, _A.__init__()
is already called before the monkeypatch - I suspect that it's because monkeypatch has to import a in order to change it, but once a is imported, the init has already been called.
unittest.mock.patch also behaves the same, supposedly, for the same reason.
Is there a way to get around this?
I thought of using a lazily evaluated singleton:
from functools import wraps
def singleton(cls):
@wraps(cls)
def wrapper_singleton(*args, **kwargs):
if not wrapper_singleton.instance:
wrapper_singleton.instance = cls(*args, **kwargs)
return wrapper_singleton.instance
wrapper_singleton.instance = None
return wrapper_singleton
This works, but for some reason I can't set debug breakpoints once my tests use this singleton... But I guess I'll open a new question regarding this issue, if indeed the global variable approach is as impossible as it seems.
Aucun commentaire:
Enregistrer un commentaire