最近、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 関数の使用方法です。これは、特定のオブジェクトの属性をモックまたは別の値に一時的に置き換えるためのテストで使用されます。
引数
このようにして、フィクスチャ内にモック化された変数を作成できます。
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 サイトの他の関連記事を参照してください。