python - 根据 call_args 模拟 Popen 以返回不同的结果
问题描述
我正在调用一个def sftp(cmdstr, server):
调用 Popen 来调用系统 sftp 客户端的函数。
我遇到的问题是我有一个使用不同参数main
调用sftp
两次的函数。第一次是文件ls
,第二次是get
文件。我已经模拟了调用,但我无法弄清楚如何分支返回值。
如果第一次调用我希望它在下面链接返回一个字符串。如果第二次调用我希望它使用 tmpdir.mkdir() 创建文件,那么文件“出现”就好像它们已被下载一样。由于稍后在代码中发生的操作,这些文件需要物理存在。
p_open = mocker.patch('mymodule.Popen', autospec=True)
mock_rv = mocker.Mock()
mock_rv.returncode = None
stdout_sftp = 'sftp> cd /upload\nsftp> ' \
'ls\n{0} {1} \n{2}' \
' \nsftp> bye\n'.format(
sftp_idf_file_list[0],
sftp_idf_file_list[1],
sftp_idf_file_list[2]
)
mock_rv.communicate.return_value = [stdout_sftp, 'output_err']
p_open.return_value = mock_rv
任何人都知道如何制作:
mock_rv.communicate.return_value = [stdout_sftp, 'output_err']
引用一个仅在设置期间调用模拟而不是之前调用的函数?
还有一点需要注意的是,代码必须与 python2.7 和 3.6 兼容。
问候,
瑞安
解决方案
答案是使用 lambda & monkeypatch。
首先我们模拟对 Popen 的调用,这样我们就拥有了所有属性,然后我们设置了返回码,这样我们就不会在主代码中出错。
最后,我们在通信中设置 lambda,这是我们实际进行 sftp 调用的地方。如果我的调用中有'ls',我想要一个目录列表,所以我从 sftp 调用返回一个标准输出的字符串。另一方面,在这种情况下,如果没有“ls”,我想运行一个 get 命令,所以不是“getting”,而是执行一个在目标目录中创建文件的方法。
stdout_sftp = 'sftp> cd /upload\nsftp> ' \
'ls\n{0} {1} \n{2}' \
' \nsftp> bye\n'.format(
sftp_idf_file_list[0],
sftp_idf_file_list[1],
sftp_idf_file_list[2]
)
def create_tmp_files(tdir, flist):
""" Used to create temp files to simulate sftp"""
for file_ in flist:
current_file = tdir.join(file_)
current_file.write('')
return "stdout", "stderror"
monkeypatch.setattr('mymodule.Popen', mocker.Mock())
monkeypatch.setattr('mymodule.Popen.return_value.returncode',
None)
monkeypatch.setattr('mymodule.Popen.return_value.communicate',
lambda x: (stdout_sftp, "stderror")
if '\nls\n' in x
else create_tmp_files(
dst_dir,
file_list))
推荐阅读
- azure-container-service - 没有拉身份验证的 Azure 容器注册表(ACR 拉角色)
- javascript - Discord.js 阅读刚刚点击的链接
- javascript - 修改js中对象数组里面的对象数组
- reactjs - 反应原生 ScrollView 不滚动而没有任何错误
- android - 尽管正确调用了observeOn(io线程),但RxJava NetworkOnMainThreadException
- kotlin - Kotlin 使用另一个对象作为默认构造函数参数创建新对象
- c++ - 在 g++ 编译器上运行 C++ 程序时 VSCode 显示错误
- reactjs - 如何在我的 React 应用程序中创建一个单独的动态窗口?
- ios - RTCClient :您必须先登录才能使用聊天 API
- google-colaboratory - 如何在 Google Colab 中使用 TreeTagger?