Testing Like a Professional: A Step-by-Step Information to Python’s Mock Library


Python's Mock Library
Picture by Creator | DALLE-3 & Canva

 

Testing software program is essential for making certain reliability and performance throughout completely different eventualities. Nevertheless, if the code implementation depends upon exterior companies, it turns into fairly a problem. That is the place mocking is available in. Python’s mock library gives instruments to create mock objects to switch actual objects, making your checks simpler to keep up. Mocking facilitates targeted testing of elements and faster testing cycles.

 

What’s Mocking?

 

Mocking is a way utilized in software program testing to simulate actual objects. Actual objects are changed by mock objects to simulate their performance, permitting you to check code in several eventualities and isolation. Mocking is particularly helpful to check particular elements of the codebase with out counting on the interplay with exterior programs, databases, or different advanced companies.

Let me clarify this idea with an instance. Contemplate that you’ve an internet software that makes use of an exterior API to retrieve information. To check with out relying on the true API, you may make a mock object that mimics the solutions of the API. This manner, you’ll be able to take a look at your software’s performance with out being depending on the true API, which could be gradual, unreliable, or not even obtainable throughout improvement.

Sounds fascinating, proper? Let’s now go over an in depth how-to for really utilizing this library.

 

Step-by-Step Information to Utilizing Mock

 

 

Step 1: Importing the Mock Library

The unittest.mock is the usual library in Python (3.3 and in all newer variations) that gives mock objects to manage the habits of actual objects. First that you must import it the unittest.mock library.

from unittest.mock import Mock, patch

 

 

Step 2: Making a Mock Object

Making a mock object is easy. As soon as imported, you’ll be able to instantiate a mock object like this:

 

Now, my_mock is a mock object that you could configure to simulate the habits of an actual object.

 

Step 3: Setting Return Values

The Mock library gives numerous methods to configure mock objects and management their habits. As an example, you’ll be able to specify what a way ought to return when known as:

my_mock.some_method.return_value="Howdy, World!"
print(my_mock.some_method())

 

Output:

 

Step 4: Setting Aspect Results

Unwanted side effects are further actions or behaviors triggered when a way of a mock object is named, comparable to elevating exceptions or executing capabilities. In addition to return values, you can too outline attributes or specify unwanted side effects like this:

def raise_exception():
    increase ValueError("An error occurred")

my_mock.some_method.side_effect = raise_exception

# It will increase a ValueError
attempt:
    my_mock.some_method()
besides ValueError as e:
    print(e)  

 

Output:

 

On this instance, ValueError raises at any time when some_method() is named.

 

Step 5: Asserting Calls

Verifying the strategy calls is essential for thorough testing. You should use assertions to specify whether or not a way was known as, when, and with what arguments.

my_mock.calculate_length('foo', 'bar')
my_mock.calculate_length.assert_called()
my_mock.calculate_length.assert_called_once()
my_mock.calculate_length.assert_called_with('foo', 'bar')
my_mock.calculate_length.assert_called_once_with('foo', 'bar')

 

  • assert_called(): Returns True if calculate_length was known as not less than as soon as
  • assert_called_once(): Returns True if calculate_length was known as precisely as soon as
  • assert_called_with('foo', 'bar'): Returns True if calculate_length was known as with the identical arguments
  • assert_called_once_with('foo', 'bar'): Returns True if calculate_length was known as precisely as soon as with the identical arguments

If any of those assertions fail on the mock object, an AssertionError will likely be raised, indicating that the anticipated habits didn’t match the precise habits of the mock.

 

Step 6: Utilizing Patch

The patch perform permits you to change actual objects with mock objects throughout checks. As mentioned earlier, that is notably helpful for simulating third-party libraries or APIs, making certain your checks stay remoted from precise implementations. To show patching, take into account the next instance perform that fetches information from the URL.

# my_module.py
import requests

def fetch_data(url):
    response = requests.get(url)
    return response.json()

 

You possibly can keep away from making actual HTTP requests by patching the ‘requests.get’ like this:

# test_my_module.py
import unittest
from unittest.mock import patch
import my_module

class TestFetchData(unittest.TestCase):
    @patch('my_module.requests.get')

    def test_fetch_data(self, mock_get):
        # Arrange the mock to return a particular response
        mock_get.return_value.json.return_value = {'key': 'worth'}
       
        # Name the perform to check
        outcome = my_module.fetch_data('http://instance.com')
       
        # Test the outcome
        self.assertEqual(outcome, {'key': 'worth'})
       
        # Confirm that requests.get was known as accurately
        mock_get.assert_called_once_with('http://instance.com')

if __name__ == '__main__':
    unittest.fundamental()

 

The patch decorator is added simply above the test_fetch_data perform to switch the requests.get perform with a mock.

 

Step 7: Mocking Lessons

You possibly can mock total lessons and their strategies to simulate interactions between objects. As an example, you’ll be able to mock a database class to check your software’s interplay with the database with out the necessity to arrange an actual database connection like this:

# database.py
class Database:
    def join(self):
        move

    def save_user(self, consumer):
        move

    def get_user(self, user_id):
        move


# test_database.py
from unittest.mock import Mock

# Making a mock database object
mock_db = Mock(spec=Database)

# Simulating technique calls
mock_db.join()
mock_db.save_user({"id": 1, "identify": "Alice"})
mock_db.get_user(1)

# Verifying that the strategies have been known as
mock_db.join.assert_called_once()
mock_db.save_user.assert_called_once_with({"id": 1, "identify": "Alice"})
mock_db.get_user.assert_called_once_with(1)

 

Wrapping Up

 
That is it for as we speak’s article on unittest.mock, a strong library for testing in Python. It permits builders to check code, making certain easy interactions between objects. With superior options like specifying unwanted side effects, asserting calls, mocking lessons, and utilizing context managers, testing numerous eventualities turns into simpler. Begin utilizing mocks in your checks as we speak to make sure higher-quality code and smoother deployments.

 
 

Kanwal Mehreen Kanwal is a machine studying engineer and a technical author with a profound ardour for information science and the intersection of AI with drugs. She co-authored the e-book “Maximizing Productiveness with ChatGPT”. As a Google Technology Scholar 2022 for APAC, she champions variety and tutorial excellence. She’s additionally acknowledged as a Teradata Variety in Tech Scholar, Mitacs Globalink Analysis Scholar, and Harvard WeCode Scholar. Kanwal is an ardent advocate for change, having based FEMCodes to empower ladies in STEM fields.

Leave a Reply

Your email address will not be published. Required fields are marked *