From 547afe1426f157c18d1d24ed014b8be1023abf8a Mon Sep 17 00:00:00 2001 From: Michael Aydinbas Date: Tue, 27 Sep 2022 21:47:33 +0200 Subject: [PATCH] refactor all tests to use python-mock (#72) * refactor all tests to use python-mock * update mocks --- poetry.lock | 72 +++++++++++---------------------------- pyproject.toml | 2 +- tests/test_cache.py | 1 - tests/test_config.py | 16 +++++---- tests/test_helloworld.py | 71 ++++++++++++++++++++++---------------- tests/test_http_helper.py | 28 +++++++-------- tests/test_profile.py | 57 ++++++++++++++++++------------- 7 files changed, 118 insertions(+), 129 deletions(-) diff --git a/poetry.lock b/poetry.lock index 84baf7e..1d86d7c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -412,21 +412,6 @@ docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] perf = ["ipython"] testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] -[[package]] -name = "importlib-resources" -version = "5.9.0" -description = "Read resources from Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] - [[package]] name = "iniconfig" version = "1.1.1" @@ -573,8 +558,6 @@ python-versions = ">=3.7" [package.dependencies] attrs = ">=17.4.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] @@ -724,19 +707,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "mock" -version = "4.0.3" -description = "Rolling backport of unittest.mock for all Pythons" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -build = ["twine", "wheel", "blurb"] -docs = ["sphinx"] -test = ["pytest (<5.4)", "pytest-cov"] - [[package]] name = "mypy" version = "0.942" @@ -975,14 +945,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "platformdirs" version = "2.5.2" @@ -1209,6 +1171,20 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +[[package]] +name = "pytest-mock" +version = "3.8.2" +description = "Thin-wrapper around the mock package for easier use with pytest" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +pytest = ">=5.0" + +[package.extras] +dev = ["pre-commit", "tox", "pytest-asyncio"] + [[package]] name = "python-dateutil" version = "2.8.2" @@ -1597,8 +1573,8 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" -python-versions = "^3.8" -content-hash = "1b5db4d4ff54096f1e1135a7c2678c6a2613c69f97b8a030e7105596759582fd" +python-versions = "^3.9" +content-hash = "b98400d2fd75045beb31ea54ad12a6a2edef2b34404b2fe33e14142e44fccf49" [metadata.files] appnope = [ @@ -1830,10 +1806,6 @@ idna = [ {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] importlib-metadata = [] -importlib-resources = [ - {file = "importlib_resources-5.9.0-py3-none-any.whl", hash = "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7"}, - {file = "importlib_resources-5.9.0.tar.gz", hash = "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681"}, -] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -2054,10 +2026,6 @@ mistune = [ {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, ] -mock = [ - {file = "mock-4.0.3-py3-none-any.whl", hash = "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62"}, - {file = "mock-4.0.3.tar.gz", hash = "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"}, -] mypy = [ {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, @@ -2189,10 +2157,6 @@ pickleshare = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] -pkgutil-resolve-name = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, @@ -2305,6 +2269,10 @@ pytest-cov = [ {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, ] +pytest-mock = [ + {file = "pytest-mock-3.8.2.tar.gz", hash = "sha256:77f03f4554392558700295e05aed0b1096a20d4a60a4f3ddcde58b0c31c8fca2"}, + {file = "pytest_mock-3.8.2-py3-none-any.whl", hash = "sha256:8a9e226d6c0ef09fcf20c94eb3405c388af438a90f3e39687f84166da82d5948"}, +] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, diff --git a/pyproject.toml b/pyproject.toml index 7b4722b..4e6d5b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,6 @@ bandit = "^1.7.4" black = "^22.3.0" flake8-docstrings = "^1.6.0" isort = "^5.10.1" -mock = "^4.0.3" mypy = "^0.942" pre-commit = "^2.18.1" pylint = "^2.13.4" @@ -24,6 +23,7 @@ pytest-cov = "^3.0.0" safety = "^2.0.0" flake8 = "^4.0.1" jupyter = "^1.0.0" +pytest-mock = "^3.8.2" [tool.black] line-length = 80 diff --git a/tests/test_cache.py b/tests/test_cache.py index 36b364a..0b3387b 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,6 +1,5 @@ import re from pathlib import Path -from typing import Optional import pytest diff --git a/tests/test_config.py b/tests/test_config.py index 873f16e..6f827df 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,8 +4,8 @@ from pathlib import Path import pytest -from mock import patch +import pygenesis.config from pygenesis.config import ( DEFAULT_SETTINGS_FILE, _write_config, @@ -33,17 +33,19 @@ def restore_settings(): _write_config(old_settings, DEFAULT_SETTINGS_FILE) -def test_settings(): +def test_create_settings_is_run_on_import(): assert DEFAULT_SETTINGS_FILE.exists() and DEFAULT_SETTINGS_FILE.is_file() -@patch("pygenesis.config.DEFAULT_CONFIG_DIR") -@patch("pygenesis.config.DEFAULT_SETTINGS_FILE") -def test_create_settings(mock_config, mock_settings, config_dir): - mock_config.return_value = config_dir - mock_settings.return_value = config_dir / "settings.ini" +def test_create_settings(config_dir, mocker): + mocker.patch.object(pygenesis.config, "DEFAULT_CONFIG_DIR", config_dir) + mocker.patch.object( + pygenesis.config, "DEFAULT_SETTINGS_FILE", config_dir / "settings.ini" + ) create_settings() + assert (config_dir / "settings.ini").is_file() + def test_load_settings(): settings = load_settings() diff --git a/tests/test_helloworld.py b/tests/test_helloworld.py index 250d5d2..c8edde4 100644 --- a/tests/test_helloworld.py +++ b/tests/test_helloworld.py @@ -1,34 +1,45 @@ -from mock import patch - from pygenesis.helloworld import logincheck, whoami from tests.test_http_helper import _generic_request_status -@patch("requests.get") -@patch("pygenesis.helloworld.load_config") -def test_whoami(mock_config, mock_requests): - mock_config.return_value = { - "GENESIS API": { - "base_url": "mocked_url", - "username": "JaneDoe", - "password": "password", - } - } - mock_requests.return_value = _generic_request_status() - - whoami() - - -@patch("requests.get") -@patch("pygenesis.helloworld.load_config") -def test_logincheck(mock_config, mock_requests): - mock_config.return_value = { - "GENESIS API": { - "base_url": "mocked_url", - "username": "JaneDoe", - "password": "password", - } - } - mock_requests.return_value = _generic_request_status() - - logincheck() +def test_whoami(mocker): + mocker.patch( + "pygenesis.helloworld.load_config", + return_value={ + "GENESIS API": { + "base_url": "mocked_url", + "username": "JaneDoe", + "password": "password", + } + }, + ) + + mocker.patch( + "pygenesis.helloworld.requests.get", + return_value=_generic_request_status(), + ) + + response = whoami() + + assert response == str(_generic_request_status().text) + + +def test_logincheck(mocker): + mocker.patch( + "pygenesis.helloworld.load_config", + return_value={ + "GENESIS API": { + "base_url": "mocked_url", + "username": "JaneDoe", + "password": "password", + } + }, + ) + mocker.patch( + "pygenesis.helloworld.requests.get", + return_value=_generic_request_status(), + ) + + response = logincheck() + + assert response == str(_generic_request_status().text) diff --git a/tests/test_http_helper.py b/tests/test_http_helper.py index 2e7c343..d3faf2f 100644 --- a/tests/test_http_helper.py +++ b/tests/test_http_helper.py @@ -1,11 +1,8 @@ import json import logging -import re -from pathlib import Path import pytest import requests -from mock import patch from pygenesis.custom_exceptions import DestatisStatusError from pygenesis.http_helper import ( @@ -59,21 +56,24 @@ def _generic_request_status( return request_status -@patch("requests.get") -@patch("pygenesis.http_helper.load_config") -def test_get_response_from_endpoint(mock_config, mock_requests): +def test_get_response_from_endpoint(mocker): """ Test once with generic API response, more detailed tests of subfunctions and specific cases below. """ - mock_config.return_value = { - "GENESIS API": { - "base_url": "mocked_url", - "username": "JaneDoe", - "password": "password", - } - } - mock_requests.return_value = _generic_request_status() + mocker.patch( + "pygenesis.http_helper.requests", return_value=_generic_request_status() + ) + mocker.patch( + "pygenesis.http_helper.load_config", + return_value={ + "GENESIS API": { + "base_url": "mocked_url", + "username": "JaneDoe", + "password": "password", + } + }, + ) get_data_from_endpoint(endpoint="endpoint", method="method", params={}) diff --git a/tests/test_profile.py b/tests/test_profile.py index fdf1c7d..d0993da 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -3,7 +3,6 @@ from pathlib import Path import pytest -from mock import patch from pygenesis.profile import change_password, remove_result from tests.test_http_helper import _generic_request_status @@ -18,12 +17,7 @@ def cache_dir(tmp_path_factory): return Path(temp_dir) -@patch("pygenesis.profile.get_config_path_from_settings") -@patch("pygenesis.profile.load_data") -@patch("pygenesis.profile.load_config") -def test_change_password( - mock_config, mock_requests, mock_config_dir, cache_dir -): +def test_change_password(mocker, cache_dir): # mock configparser to be able to test writing of new password config = ConfigParser() config["GENESIS API"] = { @@ -31,23 +25,34 @@ def test_change_password( "username": "JaneDoe", "password": "password", } - mock_config.return_value = config - mock_requests.return_value = str(_generic_request_status().text) - mock_config_dir.return_value = cache_dir / "config.ini" + mocker.patch("pygenesis.profile.load_config", return_value=config) + mocker.patch( + "pygenesis.profile.load_data", + return_value=str(_generic_request_status().text), + ) + mocker.patch( + "pygenesis.profile.get_config_path_from_settings", + return_value=cache_dir / "config.ini", + ) - change_password("new_password") + response = change_password("new_password") + assert response == str(_generic_request_status().text) -@patch("pygenesis.profile.get_config_path_from_settings") -@patch("pygenesis.profile.load_data") -@patch("pygenesis.profile.load_config") -def test_change_password_keyerror( - mock_config, mock_requests, mock_config_dir, cache_dir -): + +def test_change_password_keyerror(mocker, cache_dir): # define empty config (no password) - mock_config.return_value = {"GENESIS API": {}} - mock_requests.return_value = str(_generic_request_status().text) - mock_config_dir.return_value = cache_dir + mocker.patch( + "pygenesis.profile.load_config", return_value={"GENESIS API": {}} + ) + mocker.patch( + "pygenesis.profile.load_data", + return_value=str(_generic_request_status().text), + ) + mocker.patch( + "pygenesis.profile.get_config_path_from_settings", + return_value=cache_dir / "config.ini", + ) with pytest.raises(KeyError) as e: change_password("new_password") @@ -58,8 +63,12 @@ def test_change_password_keyerror( ) -@patch("pygenesis.profile.load_data") -def test_remove_result(mock_requests): - mock_requests.return_value = str(_generic_request_status().text) +def test_remove_result(mocker): + mocker.patch( + "pygenesis.profile.load_data", + return_value=str(_generic_request_status().text), + ) + + response = remove_result("11111-0001") - remove_result("11111-0001") + assert response == str(_generic_request_status().text)