Python 模拟工厂子 类 和方法
Python Mock Factory Sub Classes and Methods
我需要模拟 MyClassFactory
其中 returns 一个 MyClass 对象。这个对象有一个方法 getNum
我也需要模拟。我不确定如何执行此操作,因为工厂不再 returns MyClass
,而是 <MagicMock name='mock().create()'...>
.
import unittest
from mock import MagicMock, Mock, patch
class MyClass:
def getNum(self):
return 10
class MyClassFactory:
def create(self):
return MyClass()
class Runner:
def foo(self):
myClassFactory = MyClassFactory()
myClass = myClassFactory.create()
num = myClass.getNum()
if num == 10:
print("foo successful")
else:
print("foo fail, num={}".format(num))
class TestRoute(unittest.TestCase):
# Attempt at patching the methods
@patch("__main__.MyClassFactory", create=True, new=MagicMock())
@patch("__main__.MyClass", create=True, new=MagicMock())
@patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))
def test_foo_fail(self):
runner = Runner()
runner.foo()
if __name__ == '__main__':
unittest.main()
实际输出:
foo fail, num=<MagicMock name='mock().create().getNum()' id='140554774258128'>
期望的输出:
foo fail, num=11
这个<MagicMock name='mock().create().getNum()'...>
不是我想要的。我试图将 return_value=11
用于模拟方法,但它没有被调用。
TLDR:我有一个工厂需要模拟。它returns一个class。 class 有一个方法,我还需要模拟我做不到的 return_value 。基本上我想把 mock().create().getNum()
变成 11
.
这是你的第一个补丁
@patch("__main__.MyClass", create=True, new=MagicMock())
用 MagicMock() 替换了“main.MyClass”的 class 实例化。所以下一个补丁:
@patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))
最终尝试调用 MagicMock() 对象的方法而不是原始的 main.MyClass,这会导致您看到的输出。
You need to attach mocks as attributes and set up each child mock.与其在测试之前打补丁,不如在调用 foo 之前打补丁。
import unittest
from mock import MagicMock, Mock, patch
class MyClass:
def getNum(self):
return 10
class MyClassFactory:
def create(self):
return MyClass()
class Runner:
def foo(self):
myClassFactory = MyClassFactory()
myClass = myClassFactory.create()
print(myClassFactory)
print(myClass)
num = myClass.getNum()
if num == 10:
print("foo successful")
else:
print("foo fail, num={}".format(num))
class TestRoute(unittest.TestCase):
def test_foo_fail(self):
getNumMock = MagicMock(return_value = 20)
myClassMock = MagicMock()
myClassMock.getNum = getNumMock
createMock = MagicMock(return_value = myClassMock)
myClassFactoryMock = MagicMock()
createMock.attach_mock(getNumMock, "getNum")
myClassFactoryMock.attach_mock(createMock, "create")
with patch('__main__.MyClassFactory', create=True, return_value=myClassFactoryMock):
runner = Runner()
runner.foo()
if __name__ == '__main__':
unittest.main()
我需要模拟 MyClassFactory
其中 returns 一个 MyClass 对象。这个对象有一个方法 getNum
我也需要模拟。我不确定如何执行此操作,因为工厂不再 returns MyClass
,而是 <MagicMock name='mock().create()'...>
.
import unittest
from mock import MagicMock, Mock, patch
class MyClass:
def getNum(self):
return 10
class MyClassFactory:
def create(self):
return MyClass()
class Runner:
def foo(self):
myClassFactory = MyClassFactory()
myClass = myClassFactory.create()
num = myClass.getNum()
if num == 10:
print("foo successful")
else:
print("foo fail, num={}".format(num))
class TestRoute(unittest.TestCase):
# Attempt at patching the methods
@patch("__main__.MyClassFactory", create=True, new=MagicMock())
@patch("__main__.MyClass", create=True, new=MagicMock())
@patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))
def test_foo_fail(self):
runner = Runner()
runner.foo()
if __name__ == '__main__':
unittest.main()
实际输出:
foo fail, num=<MagicMock name='mock().create().getNum()' id='140554774258128'>
期望的输出:
foo fail, num=11
这个<MagicMock name='mock().create().getNum()'...>
不是我想要的。我试图将 return_value=11
用于模拟方法,但它没有被调用。
TLDR:我有一个工厂需要模拟。它returns一个class。 class 有一个方法,我还需要模拟我做不到的 return_value 。基本上我想把 mock().create().getNum()
变成 11
.
这是你的第一个补丁
@patch("__main__.MyClass", create=True, new=MagicMock())
用 MagicMock() 替换了“main.MyClass”的 class 实例化。所以下一个补丁:
@patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))
最终尝试调用 MagicMock() 对象的方法而不是原始的 main.MyClass,这会导致您看到的输出。
You need to attach mocks as attributes and set up each child mock.与其在测试之前打补丁,不如在调用 foo 之前打补丁。
import unittest
from mock import MagicMock, Mock, patch
class MyClass:
def getNum(self):
return 10
class MyClassFactory:
def create(self):
return MyClass()
class Runner:
def foo(self):
myClassFactory = MyClassFactory()
myClass = myClassFactory.create()
print(myClassFactory)
print(myClass)
num = myClass.getNum()
if num == 10:
print("foo successful")
else:
print("foo fail, num={}".format(num))
class TestRoute(unittest.TestCase):
def test_foo_fail(self):
getNumMock = MagicMock(return_value = 20)
myClassMock = MagicMock()
myClassMock.getNum = getNumMock
createMock = MagicMock(return_value = myClassMock)
myClassFactoryMock = MagicMock()
createMock.attach_mock(getNumMock, "getNum")
myClassFactoryMock.attach_mock(createMock, "create")
with patch('__main__.MyClassFactory', create=True, return_value=myClassFactoryMock):
runner = Runner()
runner.foo()
if __name__ == '__main__':
unittest.main()