[英]How to supply a mock class method for python unit test?
Let's say I have a class like this.假设我有一堂这样的课。
class SomeProductionProcess(CustomCachedSingleTon):
@classmethod
def loaddata(cls):
"""
Uses an iterator over a large file in Production for the Data pipeline.
"""
pass
Now at test time I want to change the logic inside the loaddata()
method.现在在测试时我想更改loaddata()
方法中的逻辑。 It would be a simple custom logic that doesn't process large data.这将是一个不处理大数据的简单自定义逻辑。
How do we supply custom implementation of loaddata()
at testtime using Python Mock UnitTest framework?我们如何在测试时使用 Python Mock UnitTest 框架提供loaddata()
自定义实现?
Here is a simple way to do it using mock这是使用模拟的简单方法
import mock
def new_loaddata(cls, *args, **kwargs):
# Your custom testing override
return 1
def test_SomeProductionProcess():
with mock.patch.object(SomeProductionProcess, 'loaddata', new=new_loaddata):
obj = SomeProductionProcess()
obj.loaddata() # This will call your mock method
I'd recommend using pytest
instead of the unittest
module if you're able.如果可以,我建议使用pytest
而不是unittest
模块。 It makes your test code a lot cleaner and reduces a lot of the boilerplate you get with unittest.TestCase
-style tests.它使您的测试代码更清晰,并减少了您通过unittest.TestCase
样式测试获得的大量样板。
To easily mock out a class method with a structured return_value, can use unittest.mock.Mock
.要轻松模拟具有结构化 return_value 的类方法,可以使用unittest.mock.Mock
。
from unittest.mock import Mock
mockObject = SomeProductionProcess
mockObject.loaddata = Mock(return_value=True)
EDIT:编辑:
Since you want to mock out the method with a custom implementation, you could just create a custom mock method object and swap out the original method at testing runtime.由于您想使用自定义实现来模拟方法,因此您可以创建自定义模拟方法对象并在测试运行时换出原始方法。
def custom_method(*args, **kwargs):
# do custom implementation
SomeProductionProcess.loaddata = custom_method
Lets say you have a module named awesome.py and in it, you had:假设您有一个名为awesome.py的模块,其中包含:
import time
class SomeProductionProcess(CustomCachedSingleTon):
def loaddata(self):
time.sleep(30) # simulating a long running process
return 2
Then your unittest where you mock loaddata
could look like this:然后,您模拟loaddata
可能如下所示:
import unittest
import awesome # your application module
class TestSomeProductionProcess(unittest.TestCase):
"""Example of direct monkey patching"""
def test_loaddata(self):
some_prod_proc = awesome.SomeProductionProcess()
some_prod_proc.loaddata = lambda x: 2 # will return 2 every time called
output = some_prod_proc.loaddata()
expected = 2
self.assertEqual(output, expected)
Or it could look like this:或者它看起来像这样:
import unittest
from mock import patch
import awesome # your application module
class TestSomeProductionProcess(unittest.TestCase):
"""Example of using the mock.patch function"""
@patch.object(awesome.SomeProductionProcess, 'loaddata')
def test_loaddata(self, fake_loaddata):
fake_loaddata.return_value = 2
some_prod_proc = awesome.SomeProductionProcess()
output = some_prod_proc.loaddata()
expected = 2
self.assertEqual(output, expected)
Now when you run your test, loaddata
wont take 30 seconds for those test cases.现在,当您运行测试时,对于这些测试用例, loaddata
不会花费 30 秒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.