#python #unit-testing #mocking #stringio
#python #модульное тестирование #издевательство #stringio
Вопрос:
Я новичок в модульном тестировании Python, и особенно в Mock. Как бы я смоделировал объект, с которым я мог бы сделать следующее? Мне просто нужен объект, который не приводит к сбою цикла, для завершения теста.
for ln in theMock.stdout.readlines()
Я попытался создать макет, выполнив
Mock(stdout=Mock(readlines= Lambda: []))
и
Mock(stdout=Mock(spec=file, wraps=StringIO())
но там говорится, что у объекта list нет атрибута stdout
.
Комментарии:
1. Вы имеете в виду stdin.readlines?
2. Нет, стандартный вывод.readlines() верен.
3. Зачем использовать try для чтения стандартного вывода? Вы хотите знать, что было написано в стандартном выводе?
4. Это не мой код, я просто тестирую его. Но да, это то, что он должен делать.
Ответ №1:
Как насчет этого?
from mock import Mock
readlines = Mock(return_value=[])
stdout = Mock(readlines=readlines)
theMock = Mock(stdout=stdout)
print(theMock.stdout.readlines())
Вывод:
[]
Ваш for
цикл будет просто пропущен, поскольку readlines()
вернет пустой список.
Комментарии:
1. Так чисто. Спасибо, теперь я могу идти домой!
2. Поищите в
unittest.mock
документахsys.stdout
, и вы также увидите несколько хороших решений
Ответ №2:
Мое решение, поддерживающее 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)