我有一个python类(MyClass)我是单元测试。它有一个创建数据库的外部依赖项,我想模拟该对象并检查它是否被调用。
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函数以检查是否使用" name"来调用create_db(),并返回" 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)
如何修复我的代码?
----更新---- 除了下面的依赖注入解决方案之外,还可以使用补丁执行以下操作,如下所示@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 :(得分: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)
答案 1 :(得分:0)
我无法尝试使用您的示例代码。但是你应该尝试模拟create_db
函数而不是DBCreator
类。