Skip to content

Commit

Permalink
Remove dependency to case
Browse files Browse the repository at this point in the history
  • Loading branch information
matusvalo authored and auvipy committed Sep 15, 2021
1 parent 7300741 commit fa4c4bb
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
1 change: 0 additions & 1 deletion requirements/test.txt
@@ -1,4 +1,3 @@
case>=1.3.1
pytest>=3.0,<=5.3.5
pytest-sugar>=0.9.1
pytest-rerunfailures>=6.0
24 changes: 24 additions & 0 deletions t/mocks.py
@@ -0,0 +1,24 @@
from unittest.mock import Mock

class _ContextMock(Mock):
"""Dummy class implementing __enter__ and __exit__
as the :keyword:`with` statement requires these to be implemented
in the class, not just the instance."""

def __enter__(self):
return self

def __exit__(self, *exc_info):
pass


def ContextMock(*args, **kwargs):
"""Mock that mocks :keyword:`with` statement contexts."""
obj = _ContextMock(*args, **kwargs)
obj.attach_mock(_ContextMock(), '__enter__')
obj.attach_mock(_ContextMock(), '__exit__')
obj.__enter__.return_value = obj
# if __exit__ return a value the exception is ignored,
# so it must return None here.
obj.__exit__.return_value = None
return obj
54 changes: 54 additions & 0 deletions t/unit/conftest.py
@@ -0,0 +1,54 @@
from unittest.mock import MagicMock
import pytest

sentinel = object()

class _patching:

def __init__(self, monkeypatch, request):
self.monkeypatch = monkeypatch
self.request = request

def __getattr__(self, name):
return getattr(self.monkeypatch, name)

def __call__(self, path, value=sentinel, name=None,
new=MagicMock, **kwargs):
value = self._value_or_mock(value, new, name, path, **kwargs)
self.monkeypatch.setattr(path, value)
return value

def _value_or_mock(self, value, new, name, path, **kwargs):
if value is sentinel:
value = new(name=name or path.rpartition('.')[2])
for k, v in kwargs.items():
setattr(value, k, v)
return value

def setattr(self, target, name=sentinel, value=sentinel, **kwargs):
# alias to __call__ with the interface of pytest.monkeypatch.setattr
if value is sentinel:
value, name = name, None
return self(target, value, name=name)

def setitem(self, dic, name, value=sentinel, new=MagicMock, **kwargs):
# same as pytest.monkeypatch.setattr but default value is MagicMock
value = self._value_or_mock(value, new, name, dic, **kwargs)
self.monkeypatch.setitem(dic, name, value)
return value


@pytest.fixture
def patching(monkeypatch, request):
"""Monkeypath.setattr shortcut.
Example:
.. code-block:: python
def test_foo(patching):
# execv value here will be mock.MagicMock by default.
execv = patching('os.execv')
patching('sys.platform', 'darwin') # set concrete value
patching.setenv('DJANGO_SETTINGS_MODULE', 'x.settings')
# val will be of type mock.MagicMock by default
val = patching.setitem('path.to.dict', 'KEY')
"""
return _patching(monkeypatch, request)
2 changes: 1 addition & 1 deletion t/unit/test_channel.py
Expand Up @@ -3,7 +3,6 @@
from unittest.mock import ANY, MagicMock, Mock, patch

import pytest
from case import ContextMock
from vine import promise

from amqp import spec
Expand All @@ -13,6 +12,7 @@
RecoverableConnectionError)
from amqp.serialization import dumps

from t.mocks import ContextMock

class test_Channel:

Expand Down
3 changes: 2 additions & 1 deletion t/unit/test_connection.py
Expand Up @@ -4,7 +4,6 @@
from unittest.mock import Mock, call, patch

import pytest
from case import ContextMock

from amqp import Connection, spec
from amqp.connection import SSLError
Expand All @@ -13,6 +12,8 @@
from amqp.sasl import AMQPLAIN, EXTERNAL, GSSAPI, PLAIN, SASL
from amqp.transport import TCPTransport

from t.mocks import ContextMock


class test_Connection:

Expand Down

0 comments on commit fa4c4bb

Please sign in to comment.