0

I want to make a mock object that is suitable for our teams tests.

Howerver, the default getattr behavior is not what I want. See examples below.

import mock

class A(mock.MagicMock):
    pass

a = A()
print(a.something)  # got a MagicMock without error
print(getattr(a, "something", False))  # False expected, but got a mock object

I tried to overwrite the __getattr__ method

import mock

class A(mock.MagicMock):
    def __getattr__(self, name):
        try:
            return object.__getattribute__(self, name)
        except:
            return mock.MagicMock.__getattribute__(self, name)

a = A()
print(getattr(a, "something", False))  # got a False value
print(a.something)  # got attribute error

I'm not allowed to change the "getattr(...)" in the source code.

EDIT:

The test flow may look like this
import mock

class A:
    def foo(self):
        # the "something" may not be initiated, 
        # and I want it to be 1 rather then a mock object
        stat = getattr(self, "something", 1)  
        stat *= 100
        # the client is valid only when a client connected, 
        # I want to mock it because this is a offline test.
        # Since there all many attributes like "client",
        # I don't want to overwrite every one in the MockA class
        self.client.call("done")  
        return stat

class MockA(A, mock.MagicMock):
    pass

def test_foo():
    a = MockA()
    assert a.foo() == 100
    a.something = 4
    assert a.foo() == 400
  • I'm not sure what you want to achieve - can you show us a minimal example of the code you want to test, and what do you want to mock? – MrBean Bremen Feb 01 '21 at 08:11
  • Calling attribute of a mock creates new attribute on the mock like doing mock.new_attribute. A solution is to create mock with that attribute and set it to None or False like it doesn't exist. So it will be Mock(something=False/None). – Evangelos Mar 09 '21 at 15:12

0 Answers0