Hilton Raegar
Hilton Raegar

Reputation: 63

How can I mock object with nested attributes in Python?

Consider the following code:

class Foo:
    @staticmethod
    def is_room_member(invitee, msg):
        return invitee in msg.frm.room.occupants

I want to test the method is_room_member where invitee is a string and occupants is a list of string.

If invitee = 'batman' and occupants = ['batman', 'superman'] the method is_room_member returns True.

msg is the object which needs to be mocked so that I can test this method.

How can I test this method, since it'll require this msg object which has nested attributes?

I want the test to be something like:

class Testing(unittest.TestCase):
    def test_is_room_member(self):
        occupants = ['batman', 'superman']
        # mocking 
        # msg = MagicMock()
        # msg.frm.room.occupants = occupants
        self.assertTrue(Foo.is_room_member('batman', msg))

Upvotes: 6

Views: 13623

Answers (2)

Kaiser Dandangi
Kaiser Dandangi

Reputation: 230

Since MagicMock is so magical...it is exactly what you wrote.

class Testing(unittest.TestCase):
    def test_is_room_member(self):
    occupants = ['batman', 'superman']
    msg = MagicMock()
    msg.frm.room.occupants = occupants
    print(msg.frm.room.occupants) # >>> ['batman', 'superman']
    self.assertTrue(Foo.is_room_member('batman', msg))

From the unittest docs:

Mock and MagicMock objects create all attributes and methods as you access them and store details of how they have been used.

Unless you say otherwise, everything returns a MagicMock!

Upvotes: 0

MinHwan Kim
MinHwan Kim

Reputation: 131

There is an existing answer for your question: Mocking nested properties with mock

import unittest
import mock

class Foo:
    @staticmethod
    def is_room_member(invitee, msg):
        return invitee in msg.frm.room.occupants

class Testing(unittest.TestCase):
    def test_is_room_member(self):
        occupants = ['batman', 'superman']

        # mocking
        mocked_msg = mock.MagicMock()
        mocked_msg.frm.room.occupants = occupants

        self.assertTrue(Foo.is_room_member('batman', mocked_msg))

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

Upvotes: 9

Related Questions