我已经用Python编写了一个RethinkDB的数据库包装器,这是一个引入模型的包装器(类似于Django提供的关于模型和管理器的东西)。我该如何编写单元测试?实际上,如何使用我给模型的值来测试数据库是否已更新?
我想实际查询数据库,这确实有效,但这意味着我需要为每次测试运行创建与数据库的连接(并设置数据库)。有没有办法模拟数据库或连接,所以我得到这个工作?
目前,我在测试的setUp()
方法中创建了一个Connection对象,为测试创建了一个数据库,并在tearDown()
方法中删除了上述操作。
答案 0 :(得分:2)
您可以使用unittest.mock来模拟用于实现包装器的低级API,然后使用asserts来检查包装器对API的调用。
我对django模型或rethinkdb了解不多,但看起来有点像这样。
导入uuid 进口单位测试 将unittest.mock导入为mock
import wrapper # your wrapper
class Person(wrapper.Model):
name = wrapper.CharField()
class Tests(unittest.TestCase):
def setUp(self):
# you can mock the whole low-level API module
self.mock_r = mock.Mock()
self.r_patcher = mock.patch.dict('rethinkdb', rethinkdb=self.mock_r):
self.r_patcher.start()
wrapper.connect('localhost', 1234, 'db')
def tearDown(self):
self.r_patcher.stop()
def test_create(self):
"""Test successful document creation."""
id = uuid.uuid4()
# rethinkdb.table('persons').insert(...) will return this
self.mock_r.table().insert.return_value = {
"deleted": 0,
"errors": 0,
"generated_keys": [
id
],
"inserted": 1,
"replaced": 0,
"skipped": 0,
"unchanged": 0
}
name = 'Smith'
person = wrapper.Person(name=name)
person.save()
# checking for a call like rethinkdb.table('persons').insert(...)
self.mock_r.table.assert_called_once_with('persons')
expected = {'name': name}
self.mock_r.table().insert.assert_called_once_with(expected)
# checking the generated id
self.assertEqual(person.id, id)
def test_create_error(self):
"""Test error during document creation."""
error_msg = "boom!"
self.mock_r.table().insert.return_value = {
"deleted": 0,
"errors": 1,
"first_error": error_msg
"inserted": 0,
"replaced": 0,
"skipped": 0,
"unchanged": 0
}
name = 'Smith'
person = wrapper.Person(name=name)
# expecting error
with self.assertRaises(wrapper.Error) as error:
person.save()
# checking the error message
self.assertEqual(str(error), error_msg)
这段代码很粗糙,但我希望你明白这个想法。
修改:添加return_value
并测试错误。