mercredi 26 août 2015

Python internal entity mocking

I've got a class, that I'd like to test, whether it calls a specific method of a temporary internal object or not. (ConfigParser.read)

So the object is created inside, and it's not accessible from the outside after the method exits.

In foobar.py

 import ConfigParser

 class FooBar:
     def method(self, filename):
         config=ConfigParser.ConfigParser()
         config.read(filename)
         do_some_stuff()

I'd like to test whether config.read was called.

As I understand, the patch decorator was made for this, but unfortunately the MagicMock object the testcase receives is not the same that is created inside, and I can't get near the object that lives inside the method.

I tried like this:

class TestFooBar(TestCase):

    def setUp(self):
         self.myfoobar = FooBar()

    @mock.patch('foobar.ConfigParser')
    def test_read(self,mock_foobar):
        self.myfoobar.method("configuration.ini")
        assert mock_foobar.called # THIS IS OKAY
        assert mock_foobar.read.called # THIS FAILS
        mock_foobar.read.assert_called_with("configuration.ini") # FAILS TOO

The problem is: - mock_foobar is created before the self.myfoobar.method creates the ConfigReader inside. - when debugging mock_foobar has internal data about the previous calls, but no "read" property (the inner MagicMock for mocking the read method)

Of course one way out is refactoring and giving the .read() or the init() a ConfigReader object, but it's not always possible to change the code, and I'd like to grasp the internal objects of the method without touching the module under test.

Aucun commentaire:

Enregistrer un commentaire