2017-07-20 12 views
0

私はPythonクラス(MyClass)を持っています。私はユニットテストをしています。それはデータベースを作成する外部の依存関係を持っています、私はそのオブジェクトを模倣し、それが呼び出されたことを確認したいと思います。Pythonは依存オブジェクトをモックします

from entities_database import DBCreator 

class MyClass(): 

    def __init__(self): 
     self.db = DBCreator() 

    def create(self, name): 
     value = self.db.create_db(name) 

私はinit関数をテストしたいので、モックDBCreatorが呼び出されたことを確認してください。そしてcreate関数をテストして、create_db()が "name"で呼び出されたことを確認し、valueに "name"を返しました。その結果

from entities_database import DBCreator 
from test_unit import MyClass 
import unittest 
import mock 


class MyClassTest(unittest.TestCase): 

    @mock.patch('entities_database.DBCreator', autospec=True) 
    def test_myclass_init(self, dbcreator_mock): 
     creator = mock.create_autospec(DBCreator) 
     dbcreator_mock.return_value = creator 

     myclass = MyClass() 
     assert(dbcreator_mock.called) 

は:

F 
====================================================================== 
FAIL: test_myclass_init (unit_test.MyClassTest) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/Users/paul/Data/TSC/Code/parltrack_eu/venv/lib/python3.6/site-packages/mock/mock.py", line 1305, in patched 
    return func(*args, **keywargs) 
    File "/Users/paul/Data/TSC/Code/parltrack_eu/unit_test.py", line 32, in test_myclass_init 
    assert(dbcreator_mock.called) 
AssertionError 

---------------------------------------------------------------------- 
Ran 1 test in 0.036s 

FAILED (failures=1) 

がどのように私は私のコードを修正することができます

私はこれまでのところ、私はこれを持って、どのようにこのことについて行くことがわかりませんか?

---- UPDATE ---- @Goyo

from entities_database import DBCreator 
from test_unit import MyClass 
import unittest 
import mock 


class MyClassTest(unittest.TestCase): 

    @mock.patch('test_unit.DBCreator', autospec=True) 
    def test_myclass_init(self, mock_db): 
     ''' 
     Test the initialization of MyClass 
     Test that DBCreator is initialized 
     ''' 
     creator = mock.create_autospec(DBCreator) 
     mock_db.return_value = creator 

     # Assert that the DBCreator is initialised 
     myclass = MyClass() 
     assert(mock_db.called) 

    @mock.patch('test_unit.DBCreator', autospec=True) 
    def test_myclass_create(self, mock_db): 
     ''' 
     Test the myclass.create() function 
     and assert it calls db.create_db() with the correct 
     argument 
     ''' 
     name = 'unittest' 
     myclass = MyClass() 
     myclass.create(name) 
     # Assert that create_db was called with name 
     myclass.db.create_db.assert_called_with(name) 
+0

「動作しない」問題の十分ではありません説明。詳細を記入するか、[mcve]を投稿してください。また、コンストラクタの依存関係をインスタンス化するのではなく、依存性注入を使用することをお勧めします。これは、クラスをテストしやすくします。 – Goyo

+0

@ Goyo、あなたの懸念に編集が叶うことを願っていますか? – labjunky

答えて

2

パッチがかかりにくいです。 SUTがそれを探す同じ名前空間にオブジェクトをパッチする必要があります。この場合はおそらく@mock.patch('test_unit.DBCreator', autospec=True)が必要です。依存性注入を使用して

は、この種の問題を回避し、物事をより明示的かつ明確に:

class MyClass(): 

    def __init__(self, db): 
     self.db = db 

    def create(self, name): 
     value = self.db.create_db(name) 

次に、あなたのテストで:

class MyClassTest(unittest.TestCase): 
    def test_myclass_init(self): 
     db = mock.Mock() 
     myclass = MyClass(db) 
     self.assertEqual(myclass.db, db) 

    def test_myclass_create(self): 
     db = mock.Mock() 
     myclass = MyClass(db) 
     name = mock.Mock() 
     myclass.create(name) 
     myclass.db.create_db.assert_called_once_with(name) 
0

の下に提案されているよう は別に依存性注入と以下の溶液から、1はまた、パッチで次の手順を実行することができ、私がしようとすることはできませんよあなたのサンプルコードで。しかし、create_dbの機能はDBCreatorではありません。

関連する問題