在Python中模拟标准输出
我刚接触Python的单元测试,特别是Mock这个东西。我想知道怎么模拟一个对象,这样我就可以用它做一些操作。我只需要一个不会让循环崩溃的对象,这样我才能完成测试。
for ln in theMock.stdout.readlines()
我试着通过下面的方式来创建一个模拟对象:
Mock(stdout=Mock(readlines= Lambda: []))
然后
Mock(stdout=Mock(spec=file, wraps=StringIO())
但是它提示说列表对象没有stdout
这个属性。
2 个回答
0
这是我提供的一个解决方案,它可以支持使用 stdout.readline() 和 stdout.readlines() 这两个方法:
import os
import subprocess
class MockStdout():
def __init__(self, output):
self.output = output.split('\n')
self.ix = 0
def readlines(self):
return '\n'.join(self.output)
def readline(self):
value = None
if self.ix < len(self.output):
value = self.output[self.ix]
self.ix += 1
return value
class MockSubprocess:
def __init__(self, output):
self.stdout = MockStdout(output)
real_popen = getattr(subprocess, 'Popen')
try:
setattr(subprocess, 'Popen', lambda *args, **kwargs: MockSubprocess('''First Line
Hello
there
from a stranger
standing here
Last Line
''' ))
cmd = [ 'a_command',
'--a_switch',
'--a_parameter=a_value' ]
listen_subprocess = subprocess.Popen(cmd,
cwd=os.getcwd(),
stdout=subprocess.PIPE,
universal_newlines=True)
while True:
line = listen_subprocess.stdout.readline()
if not line:
break
else:
print(line)
finally:
setattr(subprocess.Popen, '__call__', real_popen)
4
这样怎么样呢?
from mock import Mock
readlines = Mock(return_value=[])
stdout = Mock(readlines=readlines)
theMock = Mock(stdout=stdout)
print(theMock.stdout.readlines())
输出结果:
[]
你的 for
循环会被跳过,因为 readlines()
会返回一个空的列表。