pythonunit-testingmocking

Python mock object instantiation


Using Python 2.7, and mock library

How can I test that certain patched object has been initialized with some specific arguments using mock?

Here some sample code and pseudo-code:

unittest.py :

import mock
@mock.patch('mylib.SomeObject')
def test_mytest(self, mock_someobject):
  test1 = mock_someobject.return_value
  test1 = method_inside_someobject.side_effect = ['something']

  mylib.method_to_test()

  # How can I assert that method_to_test instanced SomeObject with certain arguments?
  # I further test things with that method_inside_someobject call, no problems there...

mylib.py :

from someobjectmodule import SomeObject
def method_to_test():
  obj = SomeObject(arg1=val1, arg2=val2, arg3=val3)
  obj.method_inside_someobject()

So, how can I test SomeObject was instanced with arg1=val1, arg2=val2, arg3=val3?


Solution

  • If you replaced a class with a mock, creating an instance is just another call. Assert that the right parameters have been passed to that call, for example, with mock.assert_called_with():

    mock_someobject.assert_called_with(arg1=val1, arg2=val2, arg3=val3)
    

    To illustrate, I've updated your MCVE to a working example:

    test.py:

    import mock
    import unittest
    
    import mylib
    
    
    class TestMyLib(unittest.TestCase):
        @mock.patch('mylib.SomeObject')
        def test_mytest(self, mock_someobject):
            mock_instance = mock_someobject.return_value
            mock_instance.method_inside_someobject.side_effect = ['something']
    
            retval = mylib.method_to_test()
    
            mock_someobject.assert_called_with(arg1='foo', arg2='bar', arg3='baz')
            self.assertEqual(retval, 'something')
    
    
    if __name__ == '__main__':
        unittest.main()
    

    mylib.py:

    from someobjectmodule import SomeObject
    
    def method_to_test():
        obj = SomeObject(arg1='foo', arg2='bar', arg3='baz')
        return obj.method_inside_someobject()
    

    someobjectmodule.py:

    class SomeObject(object):
        def method_inside_someobject(self):
            return 'The real thing'
    

    and running the test:

    $ python test.py
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    OK