1

I have an instance method that I want to test using mock. I am trying to substitute one of the method in this instance class with another method that takes arguments.

class to be test:

class ClassToTest():
    def compute(self):
        result = self._get_xml()
        return result

    def _get_xml(self):
        #get xml here
        return xml    

The test file:

from mock import patch
class ClassTest():

    @patch('classToTest._get_xml', _get_fake_xml)
    def computetest(self):
        test = ClassToTest()
        toassert = test.compute()

        #assert whatever
        #self.assert(...)

    def _get_fake_xml(self, objects, filename):
        py_file = os.path.abspath(__file__)
        py_dir = os.path.dirname(py_file)
        xml_file = os.path.join(py_dir, filename)
        xml_tree = objectify.parse(xml_file)
        return xml_tree.getroot()
        return xml 

Now how can I add the arguments for _get_fake_xml method in the patch

I have tried :

@patch('classToTest._get_xml', _get_fake_xml(mock.Mock(), 'filenam.xml'))

But that didn't work. Then I tried to make filename as a global variable but I get the following error:

self.filename does not exist in ClassToTest instance.

Basically I want to be able to reuse _get_fake_xml with any other filename.

Any suggestion?

momigi
  • 129
  • 1
  • 10

2 Answers2

2

So, After some thoughts, I decided to use mock .return_value.

@patch('classToTest._get_xml')
    def computetest(self, get_xml):
        get_xml.return_value = _get_fake_xml('filenam.xml')
        test = ClassToTest()
        toassert = test.compute()

I wonder thought if there is a way to add the arguments in the patch decorator.

momigi
  • 129
  • 1
  • 10
0

Could you put it in a closure? You could return a function from your _get_fake_xml method that still has access to _get_fake_xml's scope like this:

from mock import patch
class ClassTest():

    @patch('classToTest._get_xml', _get_fake_xml(mock.Mock(), 'filenam.xml'))
    def computetest(self):
        test = ClassToTest()
        toassert = test.compute()

        #assert whatever
        #self.assert(...)

    def _get_fake_xml(self, objects, filename):
        py_file = os.path.abspath(__file__)
        py_dir = os.path.dirname(py_file)
        xml_file = os.path.join(py_dir, filename)
        xml_tree = objectify.parse(xml_file)
        # don't know much about mock, but I include *a in case this is passed self
        return lambda *a: xml_tree.getroot()
dokkaebi
  • 9,004
  • 3
  • 42
  • 60
  • @AndyR it's a scope paired with a function. More on Wikipedia: http://en.wikipedia.org/wiki/Closure_(computer_science). The first example there is a Python one similar to what I used above. – dokkaebi Oct 26 '12 at 18:50