python - 如何在测试文件中从未明确存在的对象上修补深埋的方法?
问题描述
这是我的测试文件的一部分:
@pytest.fixture
def live_sftp():
sftp = SFTP(HOST, USERNAME, PASSWORD)
# add some directories and files
yield sftp
# Cleanup after test
@pytest.mark.parametrize('kwargs,expected', args_and_expected['get_files'])
@patch('<my_code>.sftp.sftp.paramiko.sftp_client.FTPClient.get')
def test_get_files(mock_get, kwargs, expected, live_sftp):
results = sorted(live_sftp.get_files(**kwargs))
assert mock_get.call_count == len(results)
assert_results_match_expected(expected, results)
我正在测试一个名为get_files
最终调用的方法get_file
。这是我正在测试的课程的缩写版本:
class SFTP(object):
def __init__(self, host, username, password, port=22, rsa_private_key_file=None):
# do stuff
@contextmanager
def create_connection(self):
transport = <do stuff to define transport>
conn = paramiko.SFTPClient.from_transport(transport)
yield conn
conn.close()
transport.close()
def get_file(self, remote_path, local_path=None, connection=None):
if not local_path:
local_path = files.create_temp_file_for_path(remote_path)
if connection:
connection.get(remote_path, local_path)
with self.create_connection() as connection:
connection.get(remote_path, local_path)
return local_path
def get_files(<kwargs>):
# this is a pseudocode version of get_files
paths = []
files = <stuff to generate list of files>
for file in files:
paths.append(self.get_file(file))
return paths
connection
是此类的一个实例,我不确定我在补丁中是否正确引用了它。这get
就是我要修补的。
我的目录结构的缩写版本是:
├── <my_code>
│ ├── __init__.py
│ ├── sftp
│ │ ├── __init__.py
│ │ ├── sftp.py
│ │ └── utilities.py
├── pytest.ini
├── requirements.txt
├── setup.py
├── test
│ ├── __init__.py
│ ├── fixtures.py
│ ├── test_sftp.py
我的测试失败了 ModuleNotFoundError: No module named '<my_code>.sftp.sftp.paramiko'; '<my_code.sftp.sftp' is not a package
。那讲得通; '<my_code>.sftp.sftp'
不是一个包;这是一个模块。但是我已经阅读了文档和其他几个 Stack Overflow 问题,但我找不到说明我想要做什么的示例;我也不能根据我对基本原则的理解(也许不多)来推断它。
也许令人困惑的问题是测试文件所做的唯一相关导入是from <my-code>.sftp import SFTP
. SFTP
当类的实例connection
被告知创建一个时,它们会产生 a ,并且get
除了 through 之外无法访问此方法connection
。
SFTP
在我的测试文件中,夹具产生了一个实例。所以也许我的问题是我只能修补与我的测试文件中的导入对象相关的东西,而我的测试文件中唯一具有该 get 方法的东西在它产生之前不存在。它从不明确存在于测试文件中。有没有办法修补connection.get
/paramiko.sftp_client.SFTPClient.get
假设这些实体都不存在于测试文件中?
编辑历史:我意识到我对我的测试文件做了一些误导和错误的陈述;我已经纠正了他们。我还删除了一个我正在考虑的建议解决方案,考虑到我之前的误导和错误陈述,它才有意义。在另一个编辑中,为了清楚起见,我在问题中移动了代码。
在进行所有编辑时进一步思考的可能解决方案:在我的夹具中,我明确覆盖create_connection
. 它是相同的,只是它在创建之后conn
和生成它之前设置conn.get
为 Mock。夹具函数必须同时返回sftp
,conn.get
我的测试才能访问它。由于不是每个测试都应该模拟conn.get
,我有两个选择:制作两个不同的夹具,或者将夹具变成一个接受do_mock
布尔值的函数,并返回一个函数,该函数又会返回(sftp, conn.get)
。第二个选项将为每个测试添加一行代码。如果有人能提出比这更简单的建议,我将不胜感激。
解决方案
推荐阅读
- xcode - SwiftUI - 将 SceneKit 场景添加到 MacOS 项目
- purescript - purescript的类型系统可以解决结节的行吗
- r - 使用 dplyr 基于 R 中的其他两列自定义变异新列
- r - sqldf() 中的 count distinct 和 tidy 代码之间相差一个
- java - 当从intellij运行时,为什么运行我的jar会导致这个异常?
- json - 通过 props 将对象从 Laravel 刀片传递到 Vue 将数值转换为字符串
- android - 关于在activity/fragment构造函数中定义资源布局id的问题
- python - 如何在seaborns中添加每组的平均线
- angular - Angular 中的 Selenium 测试问题(isStable 始终为假)
- javascript - React + D3:散点图中 Y 轴上的数据显示不正确