{"id":3608,"date":"2022-07-02T07:51:20","date_gmt":"2022-07-02T07:51:20","guid":{"rendered":"https:\/\/www.pythontutorial.net\/python-numpy\/python-stubs\/"},"modified":"2022-07-09T07:45:27","modified_gmt":"2022-07-09T07:45:27","slug":"python-stubs","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-stubs\/","title":{"rendered":"Python Stubs"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to use Python stubs to isolate parts of your program from each other for unit testing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-python-stubs'>Introduction to the Python stubs <a href=\"#introduction-to-the-python-stubs\" class=\"anchor\" id=\"introduction-to-the-python-stubs\" title=\"Anchor for Introduction to the Python stubs\">#<\/a><\/h2>\n\n\n\n<p>Stubs are test doubles that return hard-coded values. The primary purpose of stubs is to prepare a specific state of the system under test.<\/p>\n\n\n\n<p>Stubs are beneficial because they return consistent results, making the test easier to write. Also, you can run tests even if the components that stubs are present are not working yet.<\/p>\n\n\n\n<p>Suppose you need to develop an alarm system that monitors the temperature of a room like a server room. <\/p>\n\n\n\n<p>To do that you need to set up a temperature sensor device and use the data from that sensor to alert if the temperature is below or above a specific temperature.<\/p>\n\n\n\n<p>First, define a <code>Sensor<\/code> class in the <code>sensor.py<\/code> module:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> random\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Sensor<\/span>:<\/span>\n<span class=\"hljs-meta\">    @property<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">temperature<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> random.randint(<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">45<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>Sensor<\/code> class has a temperature property that returns a random temperature between 10 and 45. In the real world, the <code>Sensor<\/code> class needs to connect to the sensor device to get the actual temperature.<\/p>\n\n\n\n<p>Second, define the <code>Alarm<\/code> class that uses a <code>Sensor<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> sensor <span class=\"hljs-keyword\">import<\/span> Sensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Alarm<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, sensor=None)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self._low = <span class=\"hljs-number\">18<\/span>\n        self._high = <span class=\"hljs-number\">24<\/span>\n        self._sensor = sensor <span class=\"hljs-keyword\">or<\/span> Sensor()\n        self._is_on = <span class=\"hljs-literal\">False<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">check<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        temperature = self._sensor.temperature\n        <span class=\"hljs-keyword\">if<\/span> temperature &lt; self._low <span class=\"hljs-keyword\">or<\/span> temperature &gt; self._high:\n            self._is_on = <span class=\"hljs-literal\">True<\/span>\n\n<span class=\"hljs-meta\">    @property<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">is_on<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> self._is_on<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>By default, the <code>is_on<\/code> property of the <code>Alarm<\/code> is off (<code>False<\/code>). The <code>check()<\/code> method turns the alarm on if the temperature is lower than 18 or higher than 42. <\/p>\n\n\n\n<p>Once the <code>is_on<\/code> property of an <code>Alarm<\/code> object is on, you can send it to the alarm device to alert accordingly.<\/p>\n\n\n\n<p>Because the <code>temperature()<\/code> method of the <code>Sensor<\/code> returns a random temperature, it&#8217;ll be difficult to test various scenarios to ensure the <code>Alarm<\/code> class works properly.<\/p>\n\n\n\n<p>To resolve it, you can define a stub for the <code>Sensor<\/code> class called <code>TestSensor<\/code>. The <code>TestSensor<\/code> has the <code>temperature<\/code> property that returns a value provided when its object is initialized.<\/p>\n\n\n\n<p>Third, define the <code>TestSensor<\/code> in <code>test_sensor.py<\/code> module:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestSensor<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, temperature)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self._temperature = temperature\n\n<span class=\"hljs-meta\">    @property<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">temperature<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> self._temperature<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>TestSensor<\/code> class is like the <code>Sensor<\/code> class except that the <code>temperature<\/code> property returns a value specified in the constructor.<\/p>\n\n\n\n<p>Fourth, define a <code>TestAlarm<\/code> class in the <code>test_alarm.py<\/code> test module and import the <code>Alarm<\/code> and <code>TestSensor<\/code> from the <code>alarm.py<\/code> and <code>sensor.py<\/code> modules:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> test_sensor <span class=\"hljs-keyword\">import<\/span> TestSensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n   <span class=\"hljs-keyword\">pass<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fifth, test if the alarm is off by default:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> test_sensor <span class=\"hljs-keyword\">import<\/span> TestSensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_is_alarm_off_by_default<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm()\n        self.assertFalse(alarm.is_on) <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>test_is_alarm_off_by_default<\/code> we create a new alarm instance and use the <code>assertFalse()<\/code> method to check if the <code>is_on<\/code> property of the alarm object is <code>False<\/code>.<\/p>\n\n\n\n<p>Run the test:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python -m unittest -v<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">test_is_alarm_off_by_default (test_alarm.TestAlarm) ... ok\n\n----------------------------------------------------------------------\nRan <span class=\"hljs-number\">1<\/span> test <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-number\">0.000<\/span>s\n\nOK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Sixth, test the <code>check()<\/code> method of the <code>Alarm<\/code> class in case the temperature is too high:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> test_sensor <span class=\"hljs-keyword\">import<\/span> TestSensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_is_alarm_off_by_default<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm()\n        self.assertFalse(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_high<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">25<\/span>))\n        alarm.check()\n        self.assertTrue(alarm.is_on)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>test_check_temperature_too_high()<\/code> test method: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Create an instance of the <code>TestSensor<\/code> with temperature 25 and passes it to the <code>Alarm<\/code> constructor. <\/li><li>Call the <code>check()<\/code> method of the alarm object.<\/li><li>Use the <code>assertTrue()<\/code> to test if the <code>is_on<\/code> property of the alarm is <code>True<\/code>.<\/li><\/ul>\n\n\n\n<p>Run the test:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python -m unittest -v<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">test_check_temperature_too_high (test_alarm.TestAlarm) ... ok\ntest_is_alarm_off_by_default (test_alarm.TestAlarm) ... ok\n\n----------------------------------------------------------------------\nRan <span class=\"hljs-number\">2<\/span> tests <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-number\">0.001<\/span>s\n\nOK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The alarm is on because the temperature is higher than 24.<\/p>\n\n\n\n<p>Seventh, test the <code>check()<\/code> method of the Alarm class when the temperature is too low:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> test_sensor <span class=\"hljs-keyword\">import<\/span> TestSensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_is_alarm_off_by_default<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm()\n        self.assertFalse(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_high<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">25<\/span>))\n        alarm.check()\n        self.assertTrue(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_low<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">17<\/span>))\n        alarm.check()\n        self.assertTrue(alarm.is_on)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>test_check_temperature_too_low()<\/code> test method: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Create an instance of the <code>TestSensor<\/code> with temperature 17 and passes it to the Alarm constructor. <\/li><li>Call the <code>check()<\/code> method of the alarm object.<\/li><li>Use the <code>assertTrue()<\/code> to test if the is_on property of the alarm is True.<\/li><\/ul>\n\n\n\n<p>Run the test:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python -m unittest -v<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">test_check_temperature_too_high (test_alarm.TestAlarm) ... ok\ntest_check_temperature_too_low (test_alarm.TestAlarm) ... ok\ntest_is_alarm_off_by_default (test_alarm.TestAlarm) ... ok\n\n----------------------------------------------------------------------\nRan <span class=\"hljs-number\">3<\/span> tests <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-number\">0.001<\/span>s\n\nOK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Seventh, test the <code>check()<\/code> method of the <code>Alarm<\/code> class if the temperature is in the safe range (18, 24):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> test_sensor <span class=\"hljs-keyword\">import<\/span> TestSensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_is_alarm_off_by_default<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm()\n        self.assertFalse(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_high<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">25<\/span>))\n        alarm.check()\n        self.assertTrue(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_low<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">15<\/span>))\n        alarm.check()\n        self.assertTrue(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_normal_temperature<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm(TestSensor(<span class=\"hljs-number\">20<\/span>))\n        alarm.check()\n        self.assertFalse(alarm.is_on)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>test_check_normal_temperature()<\/code> method we create a TestSensor with the temperature 20 and pass it to the Alarm constructor. Since the temperature is in the range (18, 24), the alarm should be off.<\/p>\n\n\n\n<p>Run the test:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python -m unittest -v<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">test_check_normal_temperature (test_alarm.TestAlarm) ... ok\ntest_check_temperature_too_high (test_alarm.TestAlarm) ... ok\ntest_check_temperature_too_low (test_alarm.TestAlarm) ... ok\ntest_is_alarm_off_by_default (test_alarm.TestAlarm) ... ok\n\n----------------------------------------------------------------------\nRan <span class=\"hljs-number\">4<\/span> tests <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-number\">0.001<\/span>s\n\nOK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='using-magicmock-class-to-create-stubs'>Using MagicMock class to create stubs <a href=\"#using-magicmock-class-to-create-stubs\" class=\"anchor\" id=\"using-magicmock-class-to-create-stubs\" title=\"Anchor for Using MagicMock class to create stubs\">#<\/a><\/h2>\n\n\n\n<p>Python provides you with the <code>MagicMock<\/code> object in the <code><a href=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-unittest-mock\/\">unittest.mock<\/a><\/code> module that allows you to create stubs more easily.<\/p>\n\n\n\n<p>To create a stub for the <code>Sensor<\/code> class using the <code>MagicMock<\/code> class, you pass the <code>Sensor<\/code> class to the <code>MagicMock()<\/code> constructor:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">mock_sensor = MagicMock(Sensor)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>mock_sensor<\/code> is the new instance of the <code>MagicMock<\/code> class that mocks the <code>Sensor<\/code> class. <\/p>\n\n\n\n<p>By using the <code>mock_sensor<\/code> object, you can set its property or call a method. For example, you can assign a specific temperature e.g., 25 to the <code>temperature<\/code> property of the mock sensor like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">mock_sensor.temperature = <span class=\"hljs-number\">25<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The following shows the new version of the <code>TestAlarm<\/code> that uses the <code>MagicMock<\/code> class:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> unittest.mock <span class=\"hljs-keyword\">import<\/span> MagicMock\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n<span class=\"hljs-keyword\">from<\/span> sensor <span class=\"hljs-keyword\">import<\/span> Sensor\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">setUp<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.mock_sensor = MagicMock(Sensor)\n        self.alarm = Alarm(self.mock_sensor)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_is_alarm_off_by_default<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        alarm = Alarm()\n        self.assertFalse(alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_high<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.mock_sensor.temperature = <span class=\"hljs-number\">25<\/span>\n        self.alarm.check()\n        self.assertTrue(self.alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_low<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.mock_sensor.temperature = <span class=\"hljs-number\">15<\/span>\n        self.alarm.check()\n        self.assertTrue(self.alarm.is_on)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_normal_temperature<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.mock_sensor.temperature = <span class=\"hljs-number\">20<\/span>\n        self.alarm.check()\n        self.assertFalse(self.alarm.is_on)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='using-patch-method'>Using patch() method <a href=\"#using-patch-method\" class=\"anchor\" id=\"using-patch-method\" title=\"Anchor for Using patch() method\">#<\/a><\/h2>\n\n\n\n<p>To make it easier to work with <code>MagicMock<\/code>, you can use the <code><a href=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-patch\/\">patch()<\/a><\/code> as a decorator. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> unittest.mock <span class=\"hljs-keyword\">import<\/span> patch\n<span class=\"hljs-keyword\">from<\/span> alarm <span class=\"hljs-keyword\">import<\/span> Alarm\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAlarm<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n<span class=\"hljs-meta\">    @patch('sensor.Sensor')<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_check_temperature_too_low<\/span><span class=\"hljs-params\">(self, sensor)<\/span>:<\/span>\n        sensor.temperature = <span class=\"hljs-number\">10<\/span>\n        alarm = Alarm(sensor)\n        alarm.check()\n        self.assertTrue(alarm.is_on)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, we use a <code>@patch<\/code> decorator on the <code>test_check_temperature_too_low()<\/code> method. In the decorator, we pass the <code>sensor.Sensor<\/code> as a target to patch. <\/p>\n\n\n\n<p>Once we use the <code>@patch<\/code> decorator, the test method will have the second parameter which is an instance of the <code>MagicMock<\/code> that mocks the <code>sensor.Sensor<\/code> class.<\/p>\n\n\n\n<p>Inside the test method, we set the temperature property of the sensor to 10,  create a new instance of the Alarm class, and call <code>check()<\/code> method, and use the <code>assertTrue()<\/code> method to test if the alarm is on.<\/p>\n\n\n\n<p>Run the test:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python -m unittest -v<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">test_check_temperature_too_low (test_alarm_with_patch.TestAlarm) ... ok\n\n----------------------------------------------------------------------\nRan <span class=\"hljs-number\">1<\/span> test <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-number\">0.001<\/span>s<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Use stubs to return hard-coded values for testing.<\/li><li>Use <code>MagicMock<\/code> class of <code>unittest.mock<\/code> module to create stubs.<\/li><li>Use <code>patch()<\/code> to create <code>MagicMock<\/code> more easily.<\/li><\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"3608\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-stubs\/\"\n\t\t\t\tdata-post-title=\"Python Stubs\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"3608\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-stubs\/\"\n\t\t\t\tdata-post-title=\"Python Stubs\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to use Python stubs to isolate parts of your program from each other for unit testing.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":3553,"menu_order":14,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3608","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/3608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=3608"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/3608\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/3553"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=3608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}