2013-01-17 7 views
7

私はクラスの__init__のためのユニットテストを書き込もうとしています:スーパークラスの__init__を模擬して単体テスト用のモックオブジェクトを含む属性を作成するにはどうすればよいですか?

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

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

設定属性は、スーパーの__init__によって設定されています。私はmockを使用しています。config属性をmockオブジェクトにします。しかし、私はそれが実際に起こる方法を理解することができませんでした。ここで私はテストのために思い付くことが最高です:

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' 

は明らかに私が正しく設定属性を設定していませんよしかし、私は全く考えていない正確に私はそれを設定する必要があります。それとも、もし私がやりたいことが可能であれば。この仕事をするために私が何をする必要があるか誰にでも教えてもらえますか?

+0

観察

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() 

のように、手動でオブジェクトへ__init__をバインドすることができます。 'super'の戻り値は' config'属性を持つオブジェクトではなく、その引数に 'config'属性を追加するメソッド' __init__'を持つオブジェクトです。 – chepner

+0

それは '__init__'全体ですか?そうであれば、テストで行う構成ファイル名が渡されない場合にのみself.config.MakeDevBuildを追加します。 – jlujan

答えて

16

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

あなたが何ができるかについては、あなたがそうのように、パッチを適用するためにそれを渡すことで__init__を模擬することができますSuperDevBuildはDevBuildの基底クラスがある

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() 

あなたが本当にsuper()をモックとしたい場合、あなたはおそらく、クラスを作り、その後、どの作品が、非常に醜い..です

+1

ありがとう、最初のアプローチは私が必要としたものでした。 – khagler

関連する問題