I have this code under test:
def to_be_tested(x):
return round((x.a + x.b).c())
In my unittest I want to assert that exactly this is done with the passed x
and the result returned, so I pass a MagicMock
object as x
:
class Test_X(unittest.TestCase):
def test_x(self):
m = unittest.mock.MagicMock()
r = to_be_tested(m)
Then I check the result for being what I expect:
self.assertEqual(r._mock_new_name, '()') # created by calling
round_call = r._mock_new_parent
self.assertEqual(round_call._mock_new_name, '__round__')
c_result = round_call._mock_new_parent
self.assertEqual(c_result._mock_new_name, '()') # created by calling
c_call = c_result._mock_new_parent
self.assertEqual(c_call._mock_new_name, 'c')
add_result = c_call._mock_new_parent
self.assertEqual(add_result._mock_new_name, '()') # created by calling
add_call = add_result._mock_new_parent
self.assertEqual(add_call._mock_new_name, '__add__')
a_attribute = add_call._mock_new_parent
b_attribute = add_call.call_args[0][0]
self.assertEqual(a_attribute._mock_new_name, 'a')
self.assertEqual(b_attribute._mock_new_name, 'b')
self.assertIs(a_attribute._mock_new_parent, m)
self.assertIs(b_attribute._mock_new_parent, m)
After importing unittest.mock
I need to patch the internal structure of the mock
module in order to be able to properly magic-mock the round()
function (see https://stackoverflow.com/a/50329607/1281485 for details on that):
unittest.mock._all_magics.add('__round__')
unittest.mock._magics.add('__round__')
So, now, as I said, this works. But I find it extremely unreadable. Furthermore I needed to play around a lot to find the things like _mock_new_parent
etc. The underscore also indicates that this is a "private" attribute and shouldn't be used. The documentation doesn't mention it. It also does not mention another way of achieving what I try to.
Is there a nicer way to test returned MagicMock
objects for being created the way they should have been?