ホームページ  >  記事  >  バックエンド開発  >  Python クラスのモック化

Python クラスのモック化

王林
王林オリジナル
2024-08-28 18:32:30251ブラウズ

Mocking Python Classes

最近、Python モジュールの Pytest を使用して単体テストを作成する必要がありました。モジュールには、コンストラクター内で他のクラスが初期化されるクラスが含まれています。

いつものように、各クラス メソッドのテストを簡単に作成できるように、このクラスのフィクスチャを作成しました。この時点で、コンストラクターで開始されたさまざまなクラスをモックしようとしたときに、いくつかの問題に遭遇しました。モックは機能せず、これらのクラスのインスタンスはまだ作成されていました。

いくつかの調査を行い、オンラインで見つけたいくつかの異なるソリューションを組み合わせた後、クラスを模擬する方法を共有したいと思います。

解決

これが私がモックしようとしたクラスの例です:

class ClassA:
    def __init__(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

テスト中にこのクラスのすべてのフィールドに値を設定したいと考えています。この値は None またはクラス モックにすることができますが、クラス ClassB と ClassC の開始は望ましくありません。

私たちの場合、self.class_b と self.class_c をモックにすることにしましょう:

@pytest.fixture
def mock_class_b():
    class_b = Mock(spec=ClassB)
    return class_b

@pytest.fixture
def mock_class_c():
    class_c = Mock(spec=ClassC)
    return class_c

したがって、私たちの目的を果たすこのクラスのフィクスチャは次のようになります:

@pytest.fixture
def class_a_mock(mock_class_b, mock_class_c):
    with patch.object(target=ClassA, attribute="__init__", return_value=None) as mock_init:
        class_a = ClassA()
        class_a.class_b = mock_class_b
        class_a.class_c = mock_class_c
        class_b.count = 0
        return class_a

重要な部分は、Python の Unittest.mock モジュールにある patch.object 関数の使用方法です。これは、特定のオブジェクトの属性をモックまたは別の値に一時的に置き換えるためのテストで使用されます。

引数

  1. target=ClassA: 属性をパッチしたいオブジェクト (通常はクラス)。
  2. attribute="__init__": パッチを適用する属性の名前。
  3. return_value=None: __init__ メソッドを何も行わない関数に置き換えます

このようにして、フィクスチャ内にモック化された変数を作成できます。
patch.object

について詳しく読む

テストのヒント

このチュートリアルは、何らかの理由でクラス A のコードを変更できない場合に備えて作成しました。ただし、一般的には、ロジックを変更するのではなく、よりテストしやすくするために、可能であればコードを変更することをお勧めします。 .

クラス A を変更してテストしやすくする方法の例をいくつか示します。

オプション 1: クラス B とクラス C のインスタンスをパラメーターとして渡します。
こうすることで、フィクスチャを作成するときに、インスタンスの代わりにモックを渡すことができます。

class ClassA:
    def __init__(self, class_b_instance, class_c_instance):
        self.class_b = class_b_instance
        self.class_c = class_c_instance
        self.count = 0

オプション 2: テスト モードを示すブール変数を作成します。
このようにして、クラス A の開始時に値を取得するフィールドと取得しないフィールドを決定できます。

class ClassA:
    def __init__(self, test_mode=False):
        if not test_mode:
            self.class_b = ClassB()
            self.class_c = ClassC()
        self.count = 0

オプション 3: 別のメソッドでクラスを開始します。
このアプローチにより、テスト モジュールで set_class_variables を呼び出さないという選択肢が得られます。

class ClassA:
    def __init__(self):
        self.class_b = None
        self.class_c = None
        self.count = None

    def set_class_variables(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

これがお役に立てば幸いです! :)

以上がPython クラスのモック化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。