UNITSEST模拟找不到属性
我会收到以下错误:
attributeError:< class'workflow.workflow.task'>没有属性“提取”
这是安排代码的方式,
src
|_ workflow
|_ workflow.py
|_ tests
|_ test_extract.py
|_ data_extractor:
|_ data_extractor.py
这是 workflow.py
:
from data_extractor.data_extractor import DataExtractor
class Task:
def __init__(self) -> None:
self.extractor = DataExtractor()
def extract_data(self):
obj = self.extractor.extract()
in test_extract.py.py
:
from unittest import mock, TestCase
from workflow.workflow import Task
class TestSomeExtract(TestCase):
@mock.patch("workflow.workflow.Task.extract")
def test_extract_from_snowflake(self, mock_extract):
actual_result = Task.extract_data()
self.assertTrue(actual_result)
if __name__ == "__main__":
TestCase.main()
我认为我做对了,但是...
更新24/6:
在 test_extract.py
中:
import unittest
from unittest import mock
from workflow.workflow import DataExtractor
@mock.patch("workflow.workflow.DataExtractor")
class TestSomeExtract(unittest.TestCase):
def test_extract_from_snowflake(self, mock_extract):
mock_extract.return_value.extract.return_value = True
actual_result = DataExtractor().extract(name="entities", key="11") # return a list
self.assertTrue(actual_result)
mock_extract.assert_called_once_with(actual_result)
if __name__ == "__main__":
unittest.main()
在 workflow.py
中:
from data_extractor.data_extractor import DataExtractor
class Task:
def __init__(self, type: str, name: str) -> None:
self.name = name
self.type = type
self.extractor = DataExtractor()
def extract_data(self):
obj = self.extractor.extract(name=self.name, key=key)
除了我在测试案例中添加了 ASSERT_CALLED_ONCE_ONCE_WITH
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个工作代码示例,基于您的更新版本:
一些要突出显示的内容:
@mock.patch(“ workflow.workflow.dataextractor”)
替换dataextractor
属性属性workflow.workflow.workflow
用模拟对象 - IT不会影响data_extractor.data_extractor
软件包,因此我们不应直接使用data_extractor.data_extractor
packagedata_extractor.data_extractor。
@mock.patch(“ workflow.workflow.dataextractor”)
被翻译成这两个语句:导入workflow.workflow as Module_to_be_patched
module_to_be_patched.dataextractor = magicMock()
dataextractor
是原始data_extractor.data_extractor 对象,然后执行补丁语句,这仅影响
WorkFlow
模块。dataextractor()
,它等效于mock_extract.return_value
,然后链接excract(name) =“ supper”,key =“ 11”)
等效于.extract.return_value
。因此,完整的语法应为mock_extract.return_value.extract.extract.return_value = true
dataextractor
从workflow.workflow.workflow
,而是导入workflow.workflow
并调用其功能,依赖于dataExtractor
被我们的测试替换的事实。更新24/6:
这是一个更新的测试:
需要注意的几件事:
WorkFlow
模块,因此我们调用task> Task> Task
的初始化,然后调用extract_data
。WorkFlow
模块,因此我们模拟了其他依赖项,例如该模块的dataExtractor
。任务
类进行较小的更改。例如,将其更改为从外部获取键
参数。Here is a working code example, based in your updated version:
Some things to highlight:
@mock.patch("workflow.workflow.DataExtractor")
replaces theDataExtractor
attribute insideworkflow.workflow
package with a mock object - it doesn't affect thedata_extractor.data_extractor
package, so we shouldn't use thedata_extractor.data_extractor
package directly.@mock.patch("workflow.workflow.DataExtractor")
is translated into these two statements:import workflow.workflow as module_to_be_patched
module_to_be_patched.DataExtractor = MagicMock()
from workflow.workflow import DataExtractor
, we wouldn't use the mocked version, since we first nameDataExtractor
inside our test module to be the originaldata_extractor.data_extractor
object and only then execute the patch statement, which only affects theworkflow
module.DataExtractor()
which is equivalent tomock_extract.return_value
and then you chain the.extract(name="stuff", key="11")
which is equivalent to.extract.return_value
. Hence the full syntax should bemock_extract.return_value.extract.return_value = True
DataExtractor
fromworkflow.workflow
, but rather importworkflow.workflow
and call its functionality, relying on the fact thatDataExtractor
was replaced by our test.UPDATE 24/6:
Here is an updated test:
A couple of things to notice:
workflow
module, hence we call the initialization ofTask
and then callextract_data
.workflow
module, so we mock other dependencies like theDataExtractor
of that module.Task
class. For example, change it to get thekey
parameter from outside.