Reputation: 21218
As part of trying to test a legacy function's 'print to stdout' side-effect, I want to capture stdout for later replay. I use mock
.
goals (fulfill as many as possible!)
My implementation (below) has patching that seems a bit heavy / gross. Is there a saner way to do it? cStringIO
? Any better parts of mock
I can use, rather that my __getattr__
hack?
class StreamCapturing(object):
def __init__(self, stream):
self.captured = []
self.stream = stream
def __getattr__(self,attr):
return getattr(self.stream,attr)
def write(self, data):
self.captured.append(data)
self.stream.write(data)
import sys
import mock
with mock.patch('sys.stdout',StreamCapturing(sys.stdout)) as ctx:
sys.stdout.write('a\n')
print 'stdout'
sys.__stdout__.write("the real one\n")
print sys.stdout.captured
sys.stdout.flush()
assert getattr(sys.stdout,'captured') is None
Upvotes: 1
Views: 1350
Reputation: 48330
You don't even need to save the previous stdout python does it for you and yes use cStringIO
import sys
from cStringIO import StringIO
sys.stdout = captured = StringIO()
print "test string"
# test stuff
captured = captured.getvalue()
sys.stdout = sys.__stdout__
print "captured",captured
Upvotes: 2
Reputation: 7419
You do not need mock in this situation:
saved_stdout = sys.stdout
sys.stdout = StreamCapturing(saved_stdout)
print "stdout"
captured = "".join(sys.stdout.captured)
sys.stdout=saved_stdout
print "captured: ", captured
Upvotes: 0