Last active
March 9, 2020 03:16
-
-
Save keegoo/831531e69437a8ef6d2292d8d3819019 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ========== theory ========== | |
# | |
# Mock and MagicMock are all classes in `unitest.mock` library. | |
# | |
# ---------- The MagicMock Class ---------- | |
# A MagicMock instance can: | |
# * capture the arguments that the method is called with | |
# * count how many times it's called | |
# * return values that we specify | |
# * return the same or different values each time the mocked method is called | |
# * be made to raise errors | |
# | |
# ---------- The Mock Class ---------- | |
# `unittest.mock` provides a core Mock class removing the need to create a host of stubs throughout your test suite. | |
# | |
# MagicMock is a subclass of Mock with all the magic methods pre-created and ready to use. | |
# | |
# The patch() decorators makes it easy to temporarily replace classes in a particular module with a | |
# Mock object. By default patch() will create a MagicMock for you. | |
# | |
# ---------- pytest-mock ---------- | |
# It provides a `mocker` fixture which is a thin-wrapper around the patching API provided by the mock package. | |
# The `mocker` fixture has the same API as `mock.patch`. | |
# The `mocker` also provides other nice utilities such as `spy` and `stub`. | |
# Other names like `Mock`, `MagicMock` etc are also accessible from `mocker`. | |
# | |
# Consider following examples | |
# | |
# In Mock directly | |
from unittest import mock | |
m = mock.MagicMock() | |
assert isinstance(m.foo, mock.MagicMock) | |
assert isinstance(m.bar, mock.MagicMock) | |
assert isinstance(m(), mock.MagicMock) | |
assert m.foo is not m.bar is not m() | |
# In mocker fixture | |
from unittest import mock | |
import pytest | |
def test_do_something(mocker): | |
m = mocker.MagicMock() | |
assert isinstance(m.foo, mock.MagicMock) | |
assert isinstance(m.bar, mock.MagicMock) | |
assert isinstance(m(), mock.MagicMock) | |
assert m.foo is not m.bar is not m() | |
# ---------- Assertion for Mock object ---------- | |
m = MagicMock() | |
m.assert_called() | |
m.assert_called_once() | |
m.assert_called_with() | |
m.assert_called_once_with() | |
m.assert_any_call() | |
m.assert_has_calls() | |
m.assert_not_called() | |
# ========== mocker.path() requires a path to the function being patched ========== | |
# Consider following examples | |
# Example 1 | |
import pytest | |
def foo(): | |
return 'should not be called' | |
def get_foo(): | |
return foo() | |
def test_get_foo(mocker): | |
m = mocker.patch(__name__ + '.foo', return_value='bar') # notice: `__name__` | |
assert get_foo() == 'bar' | |
# Example 2 | |
# foo.py | |
def foo(): | |
return 'should not be called' | |
# bar.py | |
from foo import foo | |
def get_foo(): | |
return foo() | |
# test_something.py | |
import pytest | |
from bar import get_foo | |
def test_get_foo(mocker): | |
m = mocker.patch('bar.foo', return_value='bar') # notice: `bar.foo` | |
assert get_foo() == 'bar' | |
# ========== assert input for mocked function ========== | |
import pytest | |
def do_something(client, name): | |
client.greeting(name) | |
def test_it(mocker): | |
obj = mocker.MagicMock() | |
do_something(obj, 'Jim') | |
obj.greeting.assert_called_with('Jim') | |
# ========== mock standard library ========== | |
import os | |
class UnixFS: | |
@staticmethod | |
def rm(filename): | |
os.remove(filename) | |
def test_unix_fs(mocker): | |
m = mocker.patch('os.remove') | |
UnixFS.rm('file') | |
m.assert_called_once_with('file') | |
# ========== Pytest assert raise exception ========== | |
import re | |
import pytest | |
def check_email_format(email): | |
if not re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", email): | |
raise Exception("Invalid email format") | |
else: | |
return "Email format is ok" | |
def test_email_exception(): | |
with pytest.raises(Exception) as e: | |
assert check_email_format("bademail.com") | |
assert str(e.value) == "Invalid email format" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment