2011-09-09 4 views
1

レガシー関数の 'print to stdout'副作用をテストしようとする中で、後で再生するためにstdoutをキャプチャしたいと考えています。私はmockを使用します。後で再生するためにStdoutをキャプチャするわかりやすい方法は?

目標(可能な限り多くを果たす!)それは通常どおり

  • stdoutがまだ印刷しますが、追加のレコーダー
  • があり、理想的に、これは「パッチを適用」しなければならないかだけコンテキストで発生

私の実装(下記)は少し重い/グロスのようなパッチがあります。それを行うための衛生的な方法がありますか? cStringIOmockのより良い部分私は使用することができます、むしろ私の__getattr__ハック?

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 
+0

理由あなたは '__getattr__'を定義していますか?基礎となる文字列に 'write'と' flush'呼び出しを渡すだけで十分です。それ以外のコードは、出力を保存するために配列に追加するのではなく、cStringIOを使用する点を除いて、私にはよく見えます。 –

+0

'' __getattr__''は、他のすべてのメソッド呼び出しが渡すようになっています(flush、closeなど)。配列を使用するのは主に、キャプチャしたデータを表示したいときに処理する方が簡単でした。 –

答えて

0

あなたはこのような状況でモックを必要としない:あなたも前の標準出力のpythonがあなたのためにそれをしない保存する必要はありません

saved_stdout = sys.stdout 
sys.stdout = StreamCapturing(saved_stdout) 

print "stdout" 

captured = "".join(sys.stdout.captured) 
sys.stdout=saved_stdout 
print "captured: ", captured 
+0

ここで模擬はパッチ機能にはいいですね。 '' mock''コンストラクタのいずれかが私のStreamCapturingクラスよりもエレガントであるかどうか疑問に思っていました。 –

2

とはい使用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 
+0

このアプローチは、私のアプリにとっていくつかの非理想的なビットを持っています:1)途中でsys.stdoutを置き換えている人はいないと仮定します。 2)出力は 'tee'ではない –

関連する問題