Source code for boogie.testing.mock

import sys

from mock import patch

# TODO: create a more exhaustive list and move to a different module.
DEFAULT_EXTERNAL_MODULES = [
    # Django
    "django",
    "django.apps",
    "django.test.client",
    "django.conf",
    "django.conf.settings",
    "django.core",
    "django.core.exceptions",
    "django.contrib",
    "django.contrib.auth",
    "django.contrib.auth.decorators",
    "django.db",
    "django.db.models",
    "django.http",
    "django.shortcuts",
    "django.test",
    "django.urls",
    "django.urls.converters",
    "django.utils",
    "django.utils.translation",
    "django.views",
    "django.views.decorators",
    "django.views.decorators.cache",
    "django.views.decorators.clickjacking",
    "django.views.decorators.csrf",
    "django.views.decorators.gzip",
    # Rest Framework
    "rest_framework",
    "rest_framework.decorators",
    "rest_framework.relations",
    "rest_framework.response",
    "rest_framework.serializers",
    "rest_framework.utils",
    "rest_framework.utils.encoders",
    "rest_framework.viewsets",
    # Scientific
    "numpy",
    "pandas",
    # Tools
    "pytest",
    "faker",
    "model_mommy",
    "model_mommy.mommy",
    "factory",
    "factory.declarations",
]


[docs]class LightMock: """ A lightweight Mock class. It creates attributes and methods on-demand. >>> x = LightMock() >>> x.foo.bar(42) # doctests: +ELLIPSIS <LightMock ...> """ def __init__(self, *args, **kwargs): pass __method = lambda self, *args, **kwargs: LightMock() __call__ = __method __getattr__ = __method ___name__ = ___qualname__ = "mock" # Container interface __getitem__ = __method __iter__ = lambda self: iter(()) # Arithmetic operations __add__ = __sub__ = __mul__ = __truediv__ = __floordiv__ = __method __radd__ = __rsub__ = __rmul__ = __rtruediv__ = __rfloordiv__ = __method # Conversions __bool__ = lambda self: True # Pretend to be a type in some situations __mro_entries__ = lambda *args: (object,) __getstate__ = lambda self: ()
[docs]def mock_save(model, method=LightMock): """ Context manager that mocks the .save() method of a model to prevent it from hitting the database. Usage: .. code-block:: python with mock_save(model): model.name = "Hello" model.save() # it does not actually touch the db """ return patch.object(model, "save", LightMock)
_stdout = sys.stdout def mock_modules(*modules): """ Save all given modules that were not imported in sys.modules. """ cls = type("MockItem", (LightMock, type), {}) if modules == ("auto",): modules = DEFAULT_EXTERNAL_MODULES def path_hook(path): base = path.partition(".")[0] if base in modules: # It mocks all its way through a mocked module In python import # subsystem. This hack makes the implementation much simpler :) return cls() else: raise ImportError sys.path_hooks.insert(0, path_hook) for mod in modules: sys.modules.setdefault(mod, LightMock())
[docs]def assume_unique(form=None): """ Context manager that suppress checks of uniqueness during model validation. Usage: .. code-block:: python with assume_unique(model): model.slug = "repeated-slug" model.full_clean() # prevents touching the db on uniqueness checks """ from django import forms if form is None: form = forms.ModelForm return patch.object(form, "validate_unique", no_op)
# # Auxiliary functions # no_op = lambda *args, **kwargs: None cte = lambda cte: lambda *args, **kwargs: cte
[docs]def raise_exception(exception): """ Return a function that raises the given exception when called. """ if exception is not None: def action(*args, **kwargs): raise exception else: action = no_op return action