diff --git a/ch03tests/05Mocks.ipynb b/ch03tests/05Mocks.ipynb index 2149eec4..9e126182 100644 --- a/ch03tests/05Mocks.ipynb +++ b/ch03tests/05Mocks.ipynb @@ -4,54 +4,65 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Mocking" + "# Mocking in Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Definition\n", - "\n", - "**Mock**: *verb*,\n", + "## What is Mocking? \n", "\n", + "Definition \n", + "**Mock**: _verb_,\n", "1. to tease or laugh at in a scornful or contemptuous manner\n", "2. to make a replica or imitation of something\n", - "\n" + "\n", + "**Mocking in Python** \n", + "A mock object in Python substitutes and imitates a real object within a testing environment. \n", + "\n", + "\n", + "## Aims\n", + "* To learn fundamentals of unittest.mock\n", + "* To show examples of use cases\n", + "* To test other functions\n", + "\n", + "## Further reading\n", + "See last cell for further reading and real-word examples at UCL\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Mocking**\n", - "\n", - "- Replace a real object with a pretend object, which records how it is called, and can assert if it is called wrong" + "## The Mock Object\n", + "`unittest.mock` offers a base class for mocking objects called Mock. The following is an example how to define and object, call it and return id.\n" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "### Mocking frameworks\n", + "from unittest.mock import Mock\n", + "from unittest.mock import patch\n", "\n", - "* C: [CMocka](http://www.cmocka.org/)\n", - "* C++: [googletest](https://github.com/google/googletest)\n", - "* Python: [unittest.mock](http://docs.python.org/3/library/unittest.mock)" + "mock = Mock()\n", + "mock" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Recording calls with mock\n", - "\n", - "Mock objects record the calls made to them:" + "## Recording calls with mock\n", + "Mock objects record the calls made to them. See example below with various input arguments and its call `function.mock_calls`." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -61,47 +72,52 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "function(1)" + "function('word string')" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function(1000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function(number_value=500)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function(flag_variable=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "function(5, \"hello\", a=True)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "attributes": { "classes": [ @@ -110,18 +126,7 @@ "id": "" } }, - "outputs": [ - { - "data": { - "text/plain": [ - "[call(1), call(5, 'hello', a=True)]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "function.mock_calls" ] @@ -135,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "attributes": { "classes": [ @@ -144,33 +149,23 @@ "id": "" } }, - "outputs": [ - { - "data": { - "text/plain": [ - "((5, 'hello'), {'a': True})" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "name, args, kwargs = function.mock_calls[1]\n", - "args, kwargs" + "call_number = 4\n", + "_, args, kwargs = function.mock_calls[call_number]\n", + "print(f' {args}, {kwargs}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Mock objects can return different values for each call" + "## Mock objects can return different values for each call" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -179,114 +174,61 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "function(1)" + "function('word string')" ] }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'xyz'" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "function(1, \"hello\", {'a': True})" + "function(1000, \"hello\", {'a': True})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We expect an error if there are no return values left in the list:" + "We expect an error if there are no return values left in the list" ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "ename": "StopIteration", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfunction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/Documents/.config/packman/miniconda3/envs/teaching/lib/python3.7/unittest/mock.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(_mock_self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 958\u001b[0m \u001b[0;31m# in the signature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 959\u001b[0m \u001b[0m_mock_self\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mock_check_sig\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 960\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_mock_self\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mock_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 961\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 962\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Documents/.config/packman/miniconda3/envs/teaching/lib/python3.7/unittest/mock.py\u001b[0m in \u001b[0;36m_mock_call\u001b[0;34m(_mock_self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1020\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1021\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0m_callable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1022\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1023\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0m_is_exception\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1024\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mStopIteration\u001b[0m: " - ] - } - ], - "source": [ - "function()" - ] - }, - { - "cell_type": "markdown", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "### Using mocks to model test resources" + "function()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Often we want to write tests for code which interacts with remote resources. (E.g. databases, the internet, or data files.)" + "## Examples " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "### Using mocks to model test resources\n", + "Often we want to write tests for code which interacts with remote resources. (E.g. databases, the internet, or data files.)\n", "We don't want to have our tests *actually* interact with the remote resource, as this would mean our tests failed\n", - "due to lost internet connections, for example." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ + "due to lost internet connections, for example.\n", "Instead, we can use mocks to assert that our code does the right thing in terms of the *messages it sends*: the parameters of the\n", - "function calls it makes to the remote resource." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, consider the following code that downloads a map from the internet:" + "function calls it makes to the remote resource.\n", + "For example, consider the following code that downloads a map from the internet:\n" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -313,32 +255,13 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "london_map = map_at(51.5073509, -0.1277583)\n", - "from IPython.display import Image" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ + "from IPython.display import Image\n", + "\n", "%matplotlib inline\n", "Image(london_map.content)" ] @@ -352,22 +275,14 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[call('https://static-maps.yandex.ru/1.x/?', params={'z': 12, 'size': '400,400', 'll': '-0.1277583,51.5073509', 'lang': 'en_US', 'l': 'map'})]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "from unittest.mock import patch\n", "with patch.object(requests,'get') as mock_get:\n", " london_map = map_at(51.5073509, -0.1277583)\n", - " print(mock_get.mock_calls)" + " \n", + "print(mock_get.mock_calls)" ] }, { @@ -379,32 +294,50 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "def test_build_default_params():\n", + "def test_build_default_params(_base, _params):\n", " with patch.object(requests,'get') as mock_get:\n", " default_map = map_at(51.0, 0.0)\n", - " mock_get.assert_called_with(\n", - " \"https://static-maps.yandex.ru/1.x/?\",\n", - " params={\n", - " 'z':12,\n", - " 'size':'400,400',\n", - " 'll':'0.0,51.0',\n", - " 'lang':'en_US',\n", - " 'l': 'map'\n", - " }\n", - " )\n", - "test_build_default_params()" + " mock_get.assert_called_with(_base, params=_params)\n", + "\n", + "base=\"https://static-maps.yandex.ru/1.x/?\"\n", + "good_params={\n", + " 'z':12,\n", + " 'size':'400,400',\n", + " 'll':'0.0,51.0',\n", + " 'lang':'en_US',\n", + " 'l': 'map'\n", + "} \n", + "test_build_default_params(base, good_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "That was quiet, so it passed. When I'm writing tests, I usually modify one of the expectations, to something 'wrong', just to check it's not\n", - "passing \"by accident\", run the tests, then change it back!" + "That was quiet, so it passed. \n", + "When writing tests, we usually modifies one of the expectations, to something 'wrong', just to check it's not\n", + "passing \"by accident\", run the tests, then change it back:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "base=\"https://static-maps.yandex.ru/1.x/?\"\n", + "bad_params={\n", + " 'z':15,\n", + " 'size':'400,400', \n", + " 'll':'0.0,51.0',\n", + " 'lang':'en_US',\n", + " 'l': 'map'\n", + "} \n", + "test_build_default_params(base, bad_params)\n" ] }, { @@ -412,13 +345,13 @@ "metadata": {}, "source": [ "### Testing functions that call other functions\n", - "\n", - "
" + "We want to test that `partial_derivative function` does the right thing. \n", + "It is supposed to compute the derivative of a function of a vector in a particular direction. " ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "attributes": { "classes": [ @@ -437,37 +370,11 @@ " return (f_x_plus_delta - f_x) / delta" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We want to test that the above function does the right thing. It is supposed to compute the derivative of a function\n", - "of a vector in a particular direction." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "E.g.:" - ] - }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.0" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "partial_derivative(sum, [0,0,0], 1)" ] @@ -481,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -501,49 +408,55 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We made our mock a \"Magic Mock\" because otherwise, the mock results `f_x_plus_delta` and `f_x` can't be subtracted:" + "We made our mock a `MagicMock` object because otherwise, the mock results `f_x_plus_delta` and `f_x` can't be subtracted:" ] }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "MagicMock() - MagicMock()" ] }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "unsupported operand type(s) for -: 'Mock' and 'Mock'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mMock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for -: 'Mock' and 'Mock'" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Mock() - Mock()" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Further reading\n", + "\n", + "## Real-world examples at UCL \n", + "* Mock tests for NDI Optical trackers: https://github.com/SciKit-Surgery/scikit-surgerynditracker/tree/master/tests \n", + "* Mock tests for BK ultrasound machines: https://github.com/SciKit-Surgery/scikit-surgerybk/tree/master/tests\n", + "* Mock tests for Image Viewer Datasets: https://github.com/lowe-lab-ucl/napari-btrack/blob/main/napari_btrack/_tests/test_dock_widget.py\n", + "\n", + "\n", + "## Frameworks\n", + "* C: [CMocka](http://www.cmocka.org/)\n", + "* C++: [googletest](https://github.com/google/googletest)\n", + "* Python: [unittest.mock](http://docs.python.org/3/library/unittest.mock)\n", + "\n", + "## Other tutorials\n", + "* Understanding the Python Mock Object Library: https://realpython.com/python-mock-library/\n", + "* Intro to mocking in python: https://www.toptal.com/python/an-introduction-to-mocking-in-python\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -551,7 +464,7 @@ "display_name": "Mocks" }, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -565,7 +478,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.10.6" } }, "nbformat": 4,