1

djangoアプリケーションにいくつかのTestCaseクラスがあります。それらのいくつかでは、クラスを@ mock.patchで装飾することにより、外部リソースを呼び出す関数をモックアウトします。これは非常に効果的です。私のテストスイートの1つのTestCase(B()と呼びましょう)はその外部リソースに依存しているので、モックアウトしたくないし、デコレーターを追加しません。これは次のようになります。

@mock.patch("myapp.external_resource_function", new=mock.MagicMock)
class A(TestCase):
    # tests here

class B(TestBase):
    # tests here which depend on external_resource_function

Bを個別にテストすると、期待どおりに機能します。ただし、両方のテストを一緒に実行すると、Aが最初に実行されますが、関数はBでモックアウトされます。その呼び出しのモックを解除するにはどうすればよいですか?モジュールをリロードしようとしましたが、役に立ちませんでした。

4

2 に答える 2

5

パッチにはstartメソッドとstopメソッドがあります。あなたが提供したコードからわかることに基づいて、デコレータを削除し、クラスのリンクにあるsetUpメソッドとtearDownメソッドを使用します。

class A(TestCase):
  def setUp(self):
    self.patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock)
    self.MockClass1 = self.patcher1.start()

  def tearDown(self):
    self.patcher1.stop()

  def test_something(self):
    ...

>>> A('test_something').run()
于 2012-12-04T02:32:55.630 に答える
1

素晴らしい答え。Etherealの質問に関しては、パッチオブジェクトの使用は非常に柔軟です。

さまざまなパッチを必要とするテストにアプローチする1つの方法があります。setUpとtearDownは引き続き使用できますが、patch.start/stopビットは使用できません。

各テストでパッチをstart()し、finally句を使用してそれらがstopped()になることを確認します。

パッチはContextManagerのものもサポートしているため、ここには示されていませんが、これは別のオプションです。

class A(TestCase):
    patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock)
    patcher2 = patch('myapp.something_else', new=mock.MagicMock)


    def test_something(self):

        li_patcher = [self.patcher1]
        for patcher in li_patcher:
            patcher.start()


        try:
            pass
        finally:
            for patcher in li_patcher:
                patcher.stop()


    def test_something_else(self):

        li_patcher = [self.patcher1, self.patcher2]
        for patcher in li_patcher:
            patcher.start()

        try:
            pass
        finally:
            for patcher in li_patcher:
                patcher.stop()
于 2015-09-13T23:55:51.967 に答える