Skip to main content

Extending unittest-mock with moq-like validators

Project description

pymoq

from pymoq.all import *

Following the end-to-end tutorial for nbdev.

Project homepage: github

Full documentation: documentation

Install

pip install pymoq

Quickstart

Suppose we have the following setup in a python backend.

from typing import Protocol

class IWeb(Protocol):
    "Interface for accessing internet resources"
    
    def get(self, url:str, page:int, verbose:bool=False) -> str:
        "Fetches the ressource at `url` and returns it in string representation"
class RessourceFetcher:
    base_url: str = "https://some_base.com/"
    
    def __init__(self, web: IWeb):
        self._web = web
    
    def check_ressource(self, ressource_name: str, page:int, verbose:bool=False) -> bool:
        url = self.base_url + ressource_name
        ressource = self._web.get(url, page, verbose)
        
        return ressource is not None

We want to test the fetch_ressource method of RessourceFetcher. More specifically, we want to test that if the ressource is correctly returned from the source, this method should return True, otherwise False.

Setting up the mock

mock = Mock(IWeb)
mock.get\
    .setup('https://some_base.com/ressource', int, False)\
    .returns(True)

fetcher = RessourceFetcher(mock)

If the call matches the siganture defined in the setup method, the lambda in returns is called and its return value is returned:

assert fetcher.check_ressource('ressource', 1)

If any part of the signature does not match, None is returned:

assert not fetcher.check_ressource('other_ressource', 1) # wrong ressource name
assert not fetcher.check_ressource('ressource', "1") # wrong type of page argument
assert not fetcher.check_ressource('ressource', "1", verbose=True) # wrong value for verbose argument

Verification

One might want to check how often a function mock was invoked with a specific call signature. This can easily be done via the .verify method:

mock = Mock(IWeb)
fetcher = RessourceFetcher(mock)

# setup
mock.get.setup(str, int, bool).returns(True)

# act
fetcher.check_ressource('ressource', 1)
fetcher.check_ressource('ressource', 2)
fetcher.check_ressource('ressource', 1, verbose=True)

# assert
mock.get.verify(str, int, bool).times(3)
mock.get.verify(str, int, bool).more_than(1)
mock.get.verify(str, int, bool).more_than_or_equal_to(3)
mock.get.verify(str, int, bool).less_than(4)
mock.get.verify(str, int, bool).less_than_or_equal_to(3)
mock.get.verify(str, str).never()

mock.get.verify(str, AnyInt('page', 2).less_than(2), bool).times(2)

Setup sequences

mock = Mock(IWeb)
mock.get.setup('resource', int, bool).returns_sequence([1,2,3])

assert mock.get('resource', 1, True)==1
assert mock.get('resource', 2, False)==2
assert mock.get('resource', 3, True)==3

print(mock.get('ressource', 1, True))
None

Setup exceptions

class WebException(Exception):
    """Exception that describes web-access errors"""
mock = Mock(IWeb)
fetcher = RessourceFetcher(mock)

# setup failing web call
mock.get.setup('https://some_base.com/unavailable_ressource', int, bool).throws(WebException())

# act and assert exception
with pytest.raises(WebException):
    fetcher.check_ressource('unavailable_ressource', 1, True)
    
# does not raise exception if call signature does not match
fetcher.check_ressource('available_ressource', 1, True);

Deep Dive

Refer to General Structure for more detail.

Things to add

  • publish on pypi, conda

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moqpy-0.0.2.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

moqpy-0.0.2-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file moqpy-0.0.2.tar.gz.

File metadata

  • Download URL: moqpy-0.0.2.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.9

File hashes

Hashes for moqpy-0.0.2.tar.gz
Algorithm Hash digest
SHA256 5008297491bb70ae93dc61b1f77658625cdde23863edd45fd6f0397a8eb0e6f9
MD5 4fc83c0a3b73ee62fb3520659eedce47
BLAKE2b-256 0e47c2ba17b6a83f1a5bfce3f29034d0b0efd18697d0076440e0e9ef5a67830f

See more details on using hashes here.

Provenance

File details

Details for the file moqpy-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: moqpy-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.9

File hashes

Hashes for moqpy-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5b116bd24ea290b3bb4f8fe4822fa2076051f6e5417d6ec43dc9f1d8635ea42d
MD5 981f463d40f5c607a73bb795d5fd598d
BLAKE2b-256 7513808f8e370b53879f2611e749fa10504a0e429456146c35738a053d530dcc

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page