11

クラスの単体テストを作成しようとしています__init__:

def __init__(self, buildNum, configFile = "configfile.txt"):
        super(DevBuild, self).__init__(buildNum, configFile)

        if configFile == "configfile.txt":
            self.config.MakeDevBuild()

config 属性はスーパーの によって設定されます__init__。私はmockを使用していますが、config 属性をモック オブジェクトにしたいと考えています。ただし、実際にそれを実現する方法を理解することはできませんでした。テストのために私が思いつくことができる最高のものは次のとおりです。

def test_init(self):
        with patch('DevBuild.super', create=True) as mock_super:
            mock_MakeDevBuild = MagicMock()
            mock_super.return_value.config.MakeDevBuild = mock_MakeDevBuild

            # Test with manual configuration
            self.testBuild = DevBuild("42", "devconfigfile.txt")
            self.assertFalse(mock_MakeDevBuild.called)

            # Test with automated configuration
            self.testBuild = DevBuild("42")
            mock_MakeDevBuild.assert_called_once_with()

ただし、これは機能しません。エラーが発生します。

Error
Traceback (most recent call last):
  File "/Users/khagler/Projects/BuildClass/BuildClass/test_devBuild.py", line 17, in test_init
    self.testBuild = DevBuild("42")
  File "/Users/khagler/Projects/BuildClass/BuildClass/DevBuild.py", line 39, in __init__
    self.config.MakeDevBuild()
AttributeError: 'DevBuild' object has no attribute 'config'

明らかに、config 属性を正しく設定していませんが、正確にどこに設定すればよいかわかりません。または、さらに言えば、私がやりたいことが可能であれば。これを機能させるために何をする必要があるか誰か教えてもらえますか?

4

1 に答える 1

22

__init__直接設定してモックすることはできません。mock.pyの_unsupported_magicsを参照してください。

何ができるかについては、次__init__のようにパッチに渡すことでモックを作成できます。

mock_makeDevBuild = MagicMock()
def mock_init(self, buildNum, configFile):
    self.config = MagicMock()
    self.config.MakeDevBuild = mock_makeDevBuild

with patch('DevBuild.SuperDevBuild.__init__', new=mock_init):
    DevBuild("42")
    mock_makeDevBuild.assert_called_once_with()

ここSuperDevBuildで、はDevBuildの基本クラスです。

本当にモックしたい場合はsuper()、クラスを作成してから、次__init__のように手動でオブジェクトにバインドできます。

mock_makeDevBuild = MagicMock()
def get_mock_super(tp, obj):
    class mock_super(object):
        @staticmethod
        def __init__(buildNum, configFile):
            obj.config = MagicMock()
            obj.config.MakeDevBuild = mock_makeDevBuild
    return mock_super
with patch('DevBuild.super', create=True, new=get_mock_super):
    DevBuild("42")
    mock_makeDevBuild.assert_called_once_with()

これは機能しますが、かなり醜いです。

于 2013-01-26T20:44:41.793 に答える