Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python-mock: how to test if super() was called

I have the following structure:

class A(Object):
    def method(self):
        return 'a'

class B(A):
   def __init__(self, test):
       self.test = test

   def method(self):
        if self.test:
           return super(A, self).method(self)
        else:
           return 'b'

What I want to do is write a test-case which would test that if self.test is true then the super function was called and class A's method function was called.

How I can achieve this? What should I mock?

Advanced Q: What about when Class A and B are in a separate module, and they have the same name. So instead of class B I would write: class A(module1.A): does that change the mocking?

like image 968
geujv Avatar asked Aug 05 '14 15:08

geujv


People also ask

What is Side_effect in mock python?

side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.

What is MagicMock Python?

To begin with, MagicMock is a subclass of Mock . class MagicMock(MagicMixin, Mock) As a result, MagicMock provides everything that Mock provides and more. Rather than thinking of Mock as being a stripped down version of MagicMock, think of MagicMock as an extended version of Mock.


1 Answers

As @MartijnPieters points out, testing that super is called is typically a test of an implementation detail, rather than a test of a contract. Nonetheless, testing the specific implementation may still be desirable -- or the parent class may have a contract requiring the call to super. To test that super is called, use a mock, as mentioned by @mgilson. The answer in detail:

import mock, unittest

class TestB(unittest.TestCase):

    @mock.patch("A.method")
    def test_super_method(self, mock_super):
        B(True).method()
        self.assertTrue(mock_super.called)

    @mock.patch("A.method")
    def test_super_method(self, mock_super):
        B(False).method()
        self.assertFalse(mock_super.called)

You'll need to specify the full namespace in the patch. E.g., @mock.patch("module.submodule.A.method"). This can be done for any method in A, including __init__; syntax is exactly the same.

like image 102
Malina Avatar answered Sep 17 '22 12:09

Malina