I have three classes and one unittest case: 1) A.py:
class A(object):
def __new__(cls):
"""
Overriding the __new__ method to make the A a singleTon class
:return: cls.instance
"""
if not hasattr(cls, 'instance') or not cls.instance:
cls.instance = super(A, cls).__new__(cls)
return cls.instance
def execute():
print("class A")
return "Coming from class A"
2) B.py:
from A import A
class B(object):
def __init__(self):
"""
Initialize and declare any members/methods that can be passed over class that inherit this class
"""
self.a = A()
self.name = Name()
def run(self):
pass
class Name:
def __init__(self):
self.test_dict = {}
3) C.py
from B import B
class C(B):
def __init__(self):
super(C, self).__init__()
self.result = None
def run(self):
self.result = self.A.execute()
return self.result
4) test.py
import unittest
from unittest.mock import patch
from A import A
from B import B
from C import C
class TestMethods(unittest.TestCase):
@patch('A.A')
def test_basic(self, MockA):
a = MockA()
a.execute.return_value = "Testing code"
c = C()
result = c.run()
self.assertEqual(result,"Testing code")
if __name__ == '__main__':
unittest.main()
while executing test.py, I am getting following error:
Traceback (most recent call last):
File "C:\Users\davinder\AppData\Local\Continuum\Anaconda3\lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "C:/Users/davinder/PythonCodes/Test Framework/test.py", line 14, in test_basic
c = C()
File "C:\Users\davinder\PythonCodes\Test Framework\C.py", line 5, in __init__
super(C, self).__init__()
File "C:\Users\davinder\PythonCodes\Test Framework\B.py", line 8, in __init__
self.a = A()
File "C:\Users\davinder\PythonCodes\Test Framework\A.py", line 8, in __new__
cls.instance = super(A, cls).__new__(cls)
TypeError: super() argument 1 must be type, not MagicMock
----------------------------------------------------------------------
Ran 1 tests in 0.018s
FAILED (errors=1)
I want to test run() from class C.py by using different return value used from test.py(by patching). Thanks for help in advance
Edit: Even if I mock C in test.py, like this:
import unittest
from unittest.mock import patch
from A import A
from B import B
from C import C
from B import Name
class TestMethods(unittest.TestCase):
@patch('C.C')
@patch('A.A')
def test_basic(self, MockA, MockC):
a1 = MockA()
a1.execute.return_value = "Testing code"
c = MockC()
c.a = a1
c.name = Name()
result = c.run()
self.assertEqual(result,"Testing code")
if __name__ == '__main__':
unittest.main()
getting this error:
FAIL: test_basic (__main__.TestMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\davinder\AppData\Local\Continuum\Anaconda3\lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "C:/Users/davinder/PythonCodes/Test Framework/test.py", line 22, in test_basic
self.assertEqual(result,"Testing code")
AssertionError: <MagicMock name='C().run()' id='2464384921272'> != 'Testing code'
----------------------------------------------------------------------
Ran 1 tests in 0.018s
FAILED (failures=1)
I had to change your import in B.py
to be an import
instead of a from
. The error was because A
was being looked up from the B
module, so your patch would have to be @patch('B.A')
. Here's a useful read anyway on that subject: http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
Now, here's the changed code:
"""test.py"""
import unittest
from unittest.mock import patch
from c_module import C
class TestMethods(unittest.TestCase):
@patch('b_module.A')
def test_basic(self, mock_a):
mock_a.return_value.execute.return_value = "Testing code"
c = C()
result = c.run()
self.assertEqual(result,"Testing code")
if __name__ == '__main__':
unittest.main()
"""c_module.py"""
from b_module import B
class C(B):
def __init__(self):
super(C, self).__init__()
self.result = None
def run(self):
self.result = self.a.execute()
return self.result
"""b_module.py"""
from a_module import A
class B(object):
def __init__(self):
"""
Initialize and declare any members/methods that can be passed over class that inherit this class
"""
self.a = A()
self.name = Name()
def run(self):
pass
class Name:
def __init__(self):
self.test_dict = {}
"""a_module.py"""
class A(object):
def __new__(cls):
"""
Overriding the __new__ method to make the A a singleTon class
:return: cls.instance
"""
if not hasattr(cls, 'instance') or not cls.instance:
cls.instance = super(A, cls).__new__(cls)
return cls.instance
def execute():
print("class A")
return "Coming from class A"
I'd also encourage you to change your module naming. While working on this, it's hard to not conflate the modules with the classes. You can see above I've changed the module names to be snake-cased and left the classes as-is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With