47

クラス属性とそれに依存するいくつかの子クラスを定義する基本クラスがあります。

class Base(object):
    assignment = dict(a=1, b=2, c=3)

このクラスをさまざまな割り当て(空の辞書、単一項目など)で単体テストしたいのですが、これはもちろん非常に単純化されており、クラスやテストをリファクタリングする必要はありません。

私が思いついた(pytest)テストは、最終的に、その作業は

from .base import Base

def test_empty(self):
    with mock.patch("base.Base.assignment") as a:
        a.__get__ = mock.Mock(return_value={})
        assert len(Base().assignment.values()) == 0

def test_single(self):
    with mock.patch("base.Base.assignment") as a:
        a.__get__ = mock.Mock(return_value={'a':1})
        assert len(Base().assignment.values()) == 1

これはかなり複雑でハッキリしているように感じます-なぜそれが機能するのか完全には理解していません(ただし、記述子には精通しています)。モックは自動的にクラス属性を記述子に変換しますか?

より論理的に感じるソリューションは機能しません。

def test_single(self):
    with mock.patch("base.Base") as a:
        a.assignment = mock.PropertyMock(return_value={'a':1})
        assert len(Base().assignment.values()) == 1

あるいは単に

def test_single(self):
    with mock.patch("base.Base") as a:
        a.assignment = {'a':1}
        assert len(Base().assignment.values()) == 1

私が試した他のバリアントも機能しません (割り当てはテストで変更されません)。

クラス属性をモックする適切な方法は何ですか? 上記の方法よりも優れた/より理解しやすい方法はありますか?

4

5 に答える 5