[英]How to mock.patch MySQLdb.cursors?
class CanonDatabase:
def __init__(self, clean_up_db=False):
self.db = "tmg_canon_april_tokens"
self.conn = create_connection(self.db)
self.cur = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
I am trying to mock.patch MySQLdb in order to pass the constructor. 我正在尝试mock.patch MySQLdb以传递构造函数。
@mock.patch.object(MySQLdb, '__init__')
class TestDatabase(unittest.TestCase):
def setUp(self):
super(TestDatabase, self).setUp()
patch = mock.patch('atone_canon.Database.create_connection')
mock_baz = patch.start()
mock_baz.cursor.return_value = mock.MagicMock()
def tearDown(self):
super(TestDatabase, self).tearDown()
mock.patch.stopall()
def test_clean_table(self, mysql_mock):
db = CanonDatabase()
self.assertEqual(True, False)
However this fails with the following error message: 但是,此操作失败并显示以下错误消息:
File "atone_canon/Database.py", line 20, in __init__ self.cur = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
AttributeError: 'module' object has no attribute 'cursors' AttributeError:'module'对象没有属性'cursors'
I found a way: 我找到了一个方法:
If I insert this import in my unit test, without (!) even using it: 如果我在单元测试中插入此导入,没有(!)甚至使用它:
from MySQLdb.cursors import DictCursor
Then I no longer get the error, and I won't even have to mock.patch the MySQLdb wrapper: 然后我不再得到错误,我甚至不必mock.patch MySQLdb包装器:
# @mock.patch.object(MySQLdb, '__init__')
class TestDatabase(unittest.TestCase):
...
Not too happy with the solution. 对解决方案不太满意。 Generally I have difficulties with mocking classes that live outside my project (eg live in the virtualenv). 一般来说,我在模拟我的项目之外的课程时遇到困难(例如,生活在virtualenv中)。 I leave this open, so hopefully someone can show me how to mock these kind of classes. 我把它打开了,所以希望有人可以告诉我如何模拟这类课程。
First of all: make sure you have in Database.py
首先: 确保您拥有Database.py
import MySQLdb.cursors
Otherwise your mentioned error will be raised even if you don't patch anything. 否则,即使您没有修补任何内容,也会引发您提到的错误。 If you want double check it add cur=MySQLdb.cursors.DictCursor
at the top of __init__
and remove all patches: you will find the same error raised in the new line. 如果你想要仔细检查,可以在__init__
的顶部添加cur=MySQLdb.cursors.DictCursor
并删除所有补丁:你会发现在新行中引发了同样的错误。 That error will disappear if you load MySQLdb.cursors
somewhere in your context before try to point MySQLdb.cursors.DictCursor
. 如果在尝试指向MySQLdb.cursors.DictCursor
之前在上下文中的某处加载MySQLdb.cursors
则该错误将消失。 If you are wondered that you haven't see that error before is because in your production code you import MySQLdb.cursors
before use CanonDatabase()
如果您想知道以前没有看到该错误是因为在生产代码中导入MySQLdb.cursors
之前使用CanonDatabase()
Now make a test where your constructor will pass and create_connection
evil function don't try to connect anything can be obtained simply by patching just create_connection
and anything else: 现在进行一个测试,你的构造函数将通过它和create_connection
邪恶函数不尝试连接任何东西只需通过修补create_connection
和其他任何东西获得:
class TestSimpler(unittest.TestCase):
@mock.patch('atone_canon.Database.create_connection')
def test_base(self, mock_create_connection):
db = CanonDatabase()
self.assertIsNotNone(db)
Of course you can decorate test class if you want patch create_connection
for every test methods. 当然,如果你想为每个测试方法安装补丁create_connection
,你可以装饰测试类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.