2016-10-22 8 views
0

http.server.CGIHTTPRequestHandlerのカスタム子クラスをテストします。 メソッドとCGIHTTPRequestHandlerの他のすべてのメソッドは、私のテストのために無関係なものをたくさんしているので、私はそれを嘲笑したいと思います。しかし、私のテストのsetUpメソッドを@patchで飾ることでそれを達成する方法は得られません。python 3.xでパッチされたクラスを正しくインポート/デコレートする方法

/src/samplepackage/ 
    tests/ 
     __init__.py 
     sutclass_tests.py 
    __init__.py 
    parentclass.py 
    sutclass.py 

parentclass.py:

class ParentClass(): 

    def __init__(self, a, b, c): 
     print("__init__ doing much to much stuff with " + str(a) + " " + str(b) + " " + str(c)) 

sutclass.py:

from samplepackage.parentclass import ParentClass 

    class SUTClass (ParentClass): 

    def __init__(self, a, b, c, d): 
     super().__init__(a, b, c) 
     self.sutAttribute = d 

    def SUTmethod(self): 
     self.sutAttribute = self.sutAttribute * 2 
     return self.sutAttribute 
私はHOWTOのインポートを取得しない/正しくパッチを適用するクラスを飾るので、私は、最小限の例を作成しました

sutclass_tests.py:

import unittest 
from samplepackage.sutclass import SUTClass 
from unittest.mock import patch 
class SUTClassTests(unittest.TestCase): 

    @patch("samplepackage.sutclass.SUTClass.Parent.__init__") 
    def setUp(self): 
     unittest.TestCase.setUp(self) 
     self.sutClass = SUTClass(1,2,3,4) 

    def test_firstIteration(self): 
     self.assertEqual(self.sutClass.SUTmethod(), 8) 

if __name__ == '__main__': 
    unittest.main() 

にsutclass_tests.py結果を実行:

============================= ERRORS ============================= 
Traceback (most recent call last): 
    File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched 
    arg = patching.__enter__() 
    File "/usr/lib/python3.5/unittest/mock.py", line 1205, in __enter__ 
    self.target = self.getter() 
    File "/usr/lib/python3.5/unittest/mock.py", line 1375, in <lambda> 
    getter = lambda: _importer(target) 
    File "/usr/lib/python3.5/unittest/mock.py", line 1062, in _importer 
    thing = _dot_lookup(thing, comp, import_path) 
    File "/usr/lib/python3.5/unittest/mock.py", line 1051, in _dot_lookup 
    __import__(import_path) 
ImportError: No module named 'samplepackage.sutclass.SUTClass'; 'samplepackage.sutclass' is not a package 

私は(パッケージとしてそれを使用する意図はなかった)「samplepackage.sutclassは」パッケージではないことを取得します。

@patch("samplepackage.SUTClass.Parent.__init__") 

利回りに@パッチ-デコレータを変更する:

============================= ERRORS ============================= 
Traceback (most recent call last): 
    File "/usr/lib/python3.5/unittest/mock.py", line 1049, in _dot_lookup 
    return getattr(thing, comp) 
AttributeError: module 'samplepackage' has no attribute 'SUTClass' 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched 
    arg = patching.__enter__() 
    File "/usr/lib/python3.5/unittest/mock.py", line 1205, in __enter__ 
    self.target = self.getter() 
    File "/usr/lib/python3.5/unittest/mock.py", line 1375, in <lambda> 
    getter = lambda: _importer(target) 
    File "/usr/lib/python3.5/unittest/mock.py", line 1062, in _importer 
    thing = _dot_lookup(thing, comp, import_path) 
    File "/usr/lib/python3.5/unittest/mock.py", line 1051, in _dot_lookup 
    __import__(import_path) 
ImportError: No module named 'samplepackage.SUTClass' 

だから私の質問、私はそれを再利用したいとHOWTOは(SETUP-方法で私のSUTClassの親クラス(ParentClass)のパッチですマルチテストケースで)正しく?

+0

由来私のクラスで私の本当のシナリオをテストするときに、正しい挙動を示していますか? – Goyo

+0

@Goyoが完全なスタックトレースを追加しました – soriak

答えて

0

私が見つけたHow to mock a base class with python mock libraryは私の問題を解決します。しかし装飾ではなく、mock.patch.object()によって。 は、私はsutclass_tests.pyを変更:

import unittest 
from samplepackage.sutclass import SUTClass 
from unittest.mock import patch 
from unittest import mock 
class SUTClassTests(unittest.TestCase): 

    def setUp(self): 
     unittest.TestCase.setUp(self) 
     patcher = patch.object(SUTClass, '__bases__', (mock.Mock,)) 
     with patcher: 
      patcher.is_local = True 
      self.sut = SUTClass(1,2,3,4) 

    def test_firstIteration(self):  
     print(self.sut.SUTmethod()) 

if __name__ == '__main__': 
    unittest.main() 

これは私の問題を解決します(無インポートエラー)と行が `ImportError`を上げているhttp.server.CGIHTTPRequestHandler

関連する問題