Python单元测试:模拟包装其他函数的函数?
以下是我要测试的内容: test.pyPython单元测试:模拟包装其他函数的函数?,python,django,unit-testing,mocking,python-unittest,Python,Django,Unit Testing,Mocking,Python Unittest,以下是我要测试的内容: test.py class MyTest(TestCase) def test1(self): data = crawl_data() Check data lengh and current data in DB... function2() Again, Check data lengh and current data in DB... def crawl_data(): ""
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
和程序代码:
a.py
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
b.py
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
我想做的是测试function2()
。问题是,尽管function2()
调用crawl\u data()
内部
在测试中,我不希望crawl\u data()
从web抓取数据,所以我尝试模拟此函数
@patch("a.crawl_data")
def test1(self, crawl_data):
crawl_data.return_value = [("112233", "ABCDEF"), ("222233", "EFGHIJ")]
data = crawl_data()
Check data length and current data in DB
function2()
Check the database whether new data stored in DB
当我运行测试时,function2()
仍然会实时从web抓取数据
我不想模拟function2的原因是,当我开始测试时,测试框架使用虚拟数据库(由django
提供)
因此,当function2()
在内部调用它时,我要做的是将crawl\u data()
作为一个模拟
我该怎么做
编辑 我遵循了“Martijn Pieters”的解决方案♦" 给出并实现如下代码: a.py
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
b.py
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
test1.py
class MyTest(TestCase)
def test1(self):
data = crawl_data()
Check data lengh and current data in DB...
function2()
Again, Check data lengh and current data in DB...
def crawl_data():
"""
crawl data from web
"""
.
.
return web_crawled_data
from a import crawl_data
def function2():
"""
crawl data and store new data in database
"""
.
.
result = crawl_data()
.
.
update data and update Database
.
.
def sum():
return 1
from a import sum
def calling_sum():
return sum()
@patch("b.sum")
def test_sum(self, sum):
sum.return_value = 10
print(calling_sum())
结果
它打印出“1”,而不是10
我试图将@patch(“b.sum”)
更改为@patch(“b.fake\u sum”)
,以检查它是否正确导入,并且@patch(“b.fake\u sum”)
发生错误(类似于fake\u sum的东西不存在),因此我认为导入模块效果良好
仍然不起作用。您正在修补对crawl\u data
的错误引用;b
模块直接引用函数,修补a.crawl\u data
不会触及该函数。请在b
中修补它:
@patch("b.crawl_data")
def test1(self, crawl_data):
crawl_data.return_value = [("112233", "ABCDEF"), ("222233", "EFGHIJ")]
另请参见mock
模块文档的
在您的测试中使用data=crawl\u data()
没有意义,在您的模拟测试中没有意义。谢谢!但是“在您的测试中使用data=crawl\u data()
没有意义,在您的模拟测试中没有意义。”。"? 我不是以英语为母语的人,所以希望能简单地解释一下?当我按照你的建议运行测试时,模拟了crawled\u data.called()
returnFalse
在测试代码中调用function2()
,它仍然会从web上抓取数据。。不要嘲笑@user3595632:在您的问题中,您的test1
方法中有data=crawl\u data()
,就在crawl\u data.return\u value=[…]赋值之后。为什么在那里调用crawl\u data()
?这是对mock的调用,该调用将始终返回刚才分配给爬网\u数据的列表。返回\u值
。这不是一个有用的测试。@user3595632:对于您的b.py
模块,如问题所示,@patch(“b.crawl\u data”)
确实有效,在test1()
期间,在function2()
中使用名称crawl\u data()
将调用模拟。也许你没有准确地再现你的真实情况?@Martjin Pieters:我编辑了这篇文章。请检查您的编辑是否包含原始和模拟返回10。如果您看到的是1
,那么您没有运行发布的代码。@MartijnPieters我编辑过它!什么是b()
?请发布一个正确的MCVE,你实际上可以复制和运行的代码。@MartijnPieters对于你的测试犯了这样的错误,真的很抱歉。我将a.py
重命名为foo.py
,并将b.py
重命名为ham.py
,以创建一个更明显的差异。我还使用了mock\u foo\u bar
作为mock对象的名称,以明确patch()
传入的参数是mock,而不是原始参数。测试表明,该模型应用正确。这是因为ham.bar
引用是调用\u foo\u bar()
时看到的全局引用。你的MCVE不能以不同的方式工作。它真的不能复制。