如何在测试中伪造 Popen? [英] How to fake Popen in test?
问题描述
我已经成功地使用我自己的 Fake 实现或使用伪造了其他模块monkeypatch
.但在这种情况下,使用假实现或monkeypatchsubprocess.Popen
失败:
I've successfully Faked other module with my own Fake implementation or using
monkeypatch
. But in this case using both fake implementation or monkeypatch
failed for subprocess.Popen
:
- 使用
monkeypatch
失败.结果还是真开了窗口标题,而不是foo".
- Using
monkeypatch
, failed. The result still the real opened windows title, not "foo".
class TestController:
def test_get_all_windows(self, ctrl_fixture, monkeypatch):
def fake_communicate(a):
return "foo"
monkeypatch.setattr(subprocess.Popen, 'communicate', fake_communicate)
output = ctrl_fixture.get_all_windows()
print(output)
- 使用伪造也失败了,我试图模仿 原创 但是它仍然失败.
output
的结果仍然是真实的窗口标题,而不是foo" - Using faking also failed, I've tried to mimic the original but
it still failed. The result of
output
still the real windows titles, not "foo"
class FakePopen(object):
def __init__(self, args, stdout=None):
super().__init__()
self.args = args
self.stdout = stdout
def communicate(self):
return "foo"
class TestController:
def test_get_all_windows(self, ctrl_fixture, monkeypatch, mocker):
def fake_communicate(a):
return "foo"
subprocess.Popen = FakePopen
subprocess.Popen.communicate = fake_communicate
output = ctrl_fixture.get_all_windows()
print(output)
我的功能是:
def get_all_windows(self):
all_windows = ""
all_windows_proc = Popen(["wmctrl", "-l"], stdout=PIPE)
all_windows_dirty, err = all_windows_proc.communicate()
for line in all_windows_dirty.splitlines():
windows_name = line.split(None, 3)[-1].decode()
all_windows += "{}\n".format(windows_name)
return all_windows
上面的测试使用 print
而不是 assert
因为我仍然想检查输出.
The test above using print
instead of assert
cause I still want to check the output.
提前致谢.
更新解决方案
根据 munk 评论.非常感谢他.
According to munk comments. Great thanks to him.
两种解决方案都有效:
def test_get_all_windows_one(self, ctrl, monkeypatch):
window_title = b"0x006000ab 0 machine-name foo_window_title"
def fake_communicate(a):
return window_title, "err"
Lupr.controllers.controller.Popen = FakePopen
Lupr.controllers.controller.Popen.communicate = fake_communicate
output = ctrl.get_all_windows()
assert output == "foo_window_title\n"
def test_get_all_windows_two(self, ctrl, monkeypatch):
window_title = b"0x006000ab 0 machine-name foo_window_title"
def fake_communicate(a):
return window_title, "err"
monkeypatch.setattr(Lupr.controllers.controller, "Popen", FakePopen)
monkeypatch.setattr(
Lupr.controllers.controller.Popen, "communicate", fake_communicate
)
output = ctrl.get_all_windows()
assert output == "foo_window_title\n"
推荐答案
您正在修补 subprocess.Popen
,但在您测试的函数中,您使用的是 Popen
直接地.您正在更改错误的符号表.
You're patching subprocess.Popen
, but in your function under test you're using Popen
directly. You're changing the wrong symbol table.
如果您的函数在 foo.py
中,您想要修补 foo.Popen
或更改您的函数以使用 subprocess.Popen
.
If your function is in foo.py
, you want to patch foo.Popen
or change your function to use subprocess.Popen
.
这篇关于如何在测试中伪造 Popen?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!