2012-10-05 8 views
13

私はPython TestCaseクラスを持っていますが、それ以外のすべてのテストメソッドは同じ方法でオブジェクトにパッチを適用する必要があります。他のメソッドは、同じオブジェクトから別の動作を必要とします。私はmockを使用していますので、私はしました:Pythonモックのパッチデコレータを無効にする

@mock.patch('method_to_patch', mock.Mock(return_value=1)) 
class Tests(TestCase): 

    @mock.patch('method_to_patch', mock.Mock(return_value=2)) 
    def test_override(self): 
     (....) 

しかし、それは動作していません。 test_overrideを実行すると、パッチデコレータからパッチされた動作が呼び出されます。デバッグの多くの後

は、私が TestSuiteビルド中に、 test_override周り @patchが1周り Tests前に呼び出されている、と mockが順番にパッチを適用するので、クラスのデコレータはメソッドのデコレータを上書きしていることが分かりました。

この注文は正しいですか?私は反対を期待していたし、パッチをどのようにオーバーライドするかわからない... withのステートメントでは?

+0

'test_override'が' Tests'に必要ですか?私は 'test_override'と同様のテストのために別の' TestCase'を持っていると思います。すべての 'method_to_patch'が' test_override'のために別のことをしたいのであれば、別の 'TestCase'クラスを持つことが妥当であると想像することもできます。そうすれば、あなたの問題も解決し、コードを他の開発者にとってもっと読みやすくなります(「パッチ適用のパッチ適用」と比較して)。 –

+0

@SimeonVisser 'test_override'を別のクラスに移動することは、テストを構造化するために使用するルールのため、実際にはオプションではありません。それらはすべて同じテストを基準にしたテストなので、1つの 'TestCase' – Gabe

答えて

18

まあ、良い夜の睡眠と冷たいシャワーが、私が全面的な問題を再考させたことが分かります。 私はまだ嘲笑のコンセプトにはとても新しいので、それでもまだかなり沈んだわけではありません。

問題は、嘲笑されたオブジェクトにパッチを上書きする必要はないということです。それは嘲笑されたオブジェクトであり、それは私が何かをさせることができることを意味します。だから私の最初の試みでした:働いたが、以下のすべてのテストの戻り値を変更するという副作用を持っていた

@mock.patch('method_to_patch', mock.Mock(return_value=1)) 
class Tests(TestCase): 

    def test_override(self): 
     method_to_patch.return_value = 2 
     (....) 

こと。それで私は試しました:

@mock.patch('method_to_patch', mock.Mock(return_value=1)) 
class Tests(TestCase): 

    def test_override(self): 
     method_to_patch.return_value = 2 
     (....) 
     method_to_patch.return_value = 1 

それは魅力的でした。しかし、あまりにも多くのコードのように思えた。そこで、私はコンテキスト管理の道を、このように進めました:

@mock.patch('method_to_patch', mock.Mock(return_value=1)) 
class Tests(TestCase): 

    def test_override(self): 
     with mock.patch('method_to_patch', mock.Mock(return_value=2): 
      (....) 

私はそれがより明確でより簡潔に思えます。

patchデコレータが適用されている順序については、実際には正しい順序です。スタックされたデコレータがボトムアップから適用されるのと同じように、メソッドデコレータはクラスデコレータの前に呼び出されることになっています。私はそれが意味をなさないと思う、私はちょうど反対の行動を期待していた。

とにかく、これは私のような未熟な初心者の魂を将来的に助けてくれることを願っています。

関連する問題