Unit testing
Testing patterns
Object mother pattern
Python
Introduction to the Object Mother Pattern

by: Jerrish Varghese

January 20, 2023

titleImage

Introduction to the Object Mother Pattern

In the realm of software testing, one often faces the challenge of setting up complex objects or object graphs for unit tests. This setup can be cumbersome, repetitive, and clutter the test code, making it hard to understand and maintain. Here, the Object Mother pattern comes to the rescue. It is a testing pattern designed to help construct test fixtures, making tests cleaner and more readable.

What is the Object Mother Pattern?

The Object Mother pattern encapsulates the creation logic of objects needed for testing within dedicated classes known as "Object Mothers." These mothers have methods to produce objects in various predefined states, simplifying test setups and promoting the reuse of creation logic across different tests.

Benefits of Using the Object Mother Pattern

  • Readability: Reduces setup noise in test methods, focusing on the actual test logic.
  • Reusability: Centralizes object creation, allowing changes in object construction to be made in a single location.
  • Maintainability: Makes the test codebase easier to maintain and adapt as the project evolves.

Implementing the Object Mother Pattern

Consider a scenario where we need to test functionalities related to "Raid Actions" in a project management tool. We need various states of a "Raid Action" object for different tests, such as creating a new action, updating an existing one, or querying actions based on certain criteria.

Step 1: Define the Object Mother Class

We create a class named RaidActionRequestBuilder that serves as our Object Mother. This class includes methods for building Raid Action objects in different states, such as a newly created action, an updated action, or a specific action request.

class RaidActionRequestBuilder:
    request = """{
            "date": "2021-12-15",
            "projectNumber": 10699,
            "RAID": "Action",
            "assignedTo": "assignedTo@sample.com",
            "raidOperationType": "External",
            "raidOperationStatus": "Closed",
            "raidItemSynopsis": "",
            "documentHyperlink": "https://link",
            "raidEscalation": "Project",
            "actionDescription": "Action Description",
            "actionUpdates": "Action Updates",
            "createdBy": "d12345"
        }"""
    
    def __init__(self):
        self.raid_action_request = json.loads(self.request)

    @staticmethod
    def a_raid_action_request():
        return RaidActionRequestBuilder()

    def with_date(self, date):
        self.raid_action_request["date"] = date
        return self

    def with_raid(self, raid):
        self.raid_action_request["RAID"] = raid
        return self

    def with_assigned_to(self, assigned_to):
        self.raid_action_request["assignedTo"] = assigned_to
        return self

    def build(self):
        return self.raid_action_request


class RaidActionRequestInvalidData:
    DATE_INVALID = RaidActionRequestBuilder.a_raid_action_request().with_date("invalid-date-format").build()

    RAID_MISSING = RaidActionRequestBuilder.a_raid_action_request().with_raid(None).build()

    RAID_EMPTY = RaidActionRequestBuilder.a_raid_action_request().with_raid(" ").build()

    ASSIGNED_TO_MISSING = RaidActionRequestBuilder.a_raid_action_request().with_assigned_to(None).build()

    ASSIGNED_TO_EMPTY = RaidActionRequestBuilder.a_raid_action_request().with_assigned_to(" ").build()

Step 2: Utilize the Object Mother in Tests

When writing tests, instead of manually constructing Raid Action objects, we use the Object Mother to obtain pre-configured instances.

def test_create_raid_action_success():
    request = RaidActionRequestBuilder.a_raid_action_request().build()
    # Test logic...

This approach keeps our tests clean and focused, abstracting away the complexities of object creation.

Advanced Usage

The Object Mother pattern can be extended to cover more complex scenarios, such as invalid data sets for testing error handling. By defining methods within the Object Mother that return objects with intentionally invalid data, testers can easily write tests to ensure the application gracefully handles these cases.

Conclusion

The Object Mother pattern is a powerful tool in the software developer's testing arsenal, especially valuable in projects with complex domain models or extensive setup requirements for unit tests. By abstracting object creation into dedicated classes, it enhances the clarity, reusability, and maintainability of test code, making it an essential pattern for efficient and effective testing strategies.

Encouragement to Try

Implementing the Object Mother pattern can initially seem like additional work, especially for small projects. However, as projects grow and evolve, the benefits become increasingly apparent. Encouraging developers to experiment with this pattern in their testing practices can lead to more maintainable and readable test suites, ultimately contributing to the overall quality of the software development lifecycle.

contact us

Get started now

Get a quote for your project.
logofooter
title_logo

USA

Edstem Technologies LLC
254 Chapman Rd, Ste 208 #14734
Newark, Delaware 19702 US

INDIA

Edstem Technologies Pvt Ltd
Office No-2B-1, Second Floor
Jyothirmaya, Infopark Phase II
Ernakulam, Kerala 682303

© 2024 — Edstem All Rights Reserved

Privacy PolicyTerms of Use