Why does unittest.mock fail when the constructor of the production class accepts additional arguments?

I'm having a problem, which I think may be a bug with the libraries I use. However, I'm pretty new to the python, unittest and unittest.mock libraries, so this might just be a hole in my understanding.

When adding tests to some production code, I ran into an error, I released a minimal sample that reproduces the problem:

import unittest
import mock

class noCtorArg:
    def __init__(self):
        pass
    def okFunc(self):
        raise NotImplemented


class withCtorArg:
    def __init__(self,obj):
        pass
    def notOkFunc(self):
        raise NotImplemented
    def okWithArgFunc(self, anArgForMe):
        raise NotImplemented

class BasicTestSuite(unittest.TestCase):
    """Basic test Cases."""

    # passes
    def test_noCtorArg_okFunc(self):
        mockSUT = mock.MagicMock(spec=noCtorArg)
        mockSUT.okFunc()
        mockSUT.assert_has_calls([mock.call.okFunc()])

    # passes
    def test_withCtorArg_okWithArgFuncTest(self):
        mockSUT = mock.MagicMock(spec=withCtorArg)
        mockSUT.okWithArgFunc("testing")
        mockSUT.assert_has_calls([mock.call.okWithArgFunc("testing")])

    # fails
    def test_withCtorArg_doNotOkFuncTest(self):
        mockSUT = mock.MagicMock(spec=withCtorArg)
        mockSUT.notOkFunc()
        mockSUT.assert_has_calls([mock.call.notOkFunc()])


if __name__ == '__main__':
    unittest.main()

How I run the tests, and the output is as follows:

E:\work>python -m unittest testCopyFuncWithMock
.F.
======================================================================
FAIL: test_withCtorArg_doNotOkFuncTest (testCopyFuncWithMock.BasicTestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testCopyFuncWithMock.py", line 38, in test_withCtorArg_doNotOkFuncTest
    mockSUT.assert_has_calls([mock.call.notOkFunc()])
  File "C:\Python27\lib\site-packages\mock\mock.py", line 969, in assert_has_calls
    ), cause)
  File "C:\Python27\lib\site-packages\six.py", line 718, in raise_from
    raise value
AssertionError: Calls not found.
Expected: [call.notOkFunc()]
Actual: [call.notOkFunc()]

----------------------------------------------------------------------
Ran 3 tests in 0.004s

FAILED (failures=1)

I am using python 2.7.11, with the mock version 2.0.0 installed via pip.

Any suggestions on what I'm doing wrong? Or does it look like a bug in the library?

+4
2

, , assert, .

:

mockSUT.assert_has_calls(calls=[mock.call.notOkFunc()])

:

mockSUT.assert_has_calls(calls=[mock.call.notOkFunc()], any_order=True)

:

TypeError("'obj' parameter lacking default value")

, withCtorArg obj . , :

TypeError: __init__() takes exactly 2 arguments (1 given)

, mock , , TypeError.

:

class withCtorArg:
    def __init__(self, obj = None):
        pass
    def notOkFunc(self):
        pass
    def okWithArgFunc(self, anArgForMe):
        pass

None obj .

+3

, , , Mock, . advance512, , !

, , , :

# passes
@mock.patch ('mymodule.noCtorArg')
def test_noCtorArg_okFunc(self, noCtorArgMock):
    mockSUT = noCtorArg.return_value
    mockSUT.okFunc()
    mockSUT.assert_has_calls([mock.call.okFunc()])

# passes
@mock.patch ('mymodule.withCtorArg')
def test_withCtorArg_okWithArgFuncTest(self, withCtorArgMock):
    mockSUT = withCtorArg.return_value
    mockSUT.okWithArgFunc("testing")
    mockSUT.assert_has_calls([mock.call.okWithArgFunc("testing")])

# now passes
@mock.patch ('mymodule.withCtorArg')
def test_withCtorArg_doNotOkFuncTest(self, withCtorArgMock):
    mockSUT = withCtorArg.return_value
    mockSUT.notOkFunc()
    mockSUT.assert_has_calls([mock.call.notOkFunc()], any_order=True)

:

, spec. , SUT , .

, , :

class withCtorArg:
    def __init__(self,obj):
        pass
    def notOkFunc(self):
        raise NotImplemented
    def okWithArgFunc(self, anArgForMe):
        raise NotImplemented

class wrapped_withCtorArg(withCtorArg):
    def __init__(self):
        super(None)

class BasicTestSuite(unittest.TestCase):
    """Basic test Cases."""

    # now passes
    def test_withCtorArg_doNotOkFuncTest(self):
        mockSUT = mock.MagicMock(spec=wrapped_withCtorArg)
        mockSUT.notOkFunc()
        #mockSUT.doesntExist() #causes the test to fail. "Mock object has no attribute 'doesntExist'"
        assert isinstance (mockSUT, withCtorArg)
        mockSUT.assert_has_calls([mock.call.notOkFunc()], any_order=True)
+2

All Articles