2015-02-05 17 views
3
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) 

我正在嘗試mock.patch MySQLdb以傳遞構造函數。如何mock.patch MySQLdb.cursors?

@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) 

但是這個失敗,出現以下錯誤信息:

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'

我找到了一種方法:(!)

如果我在單元測試中插入此進口,甚至不需要使用它:

from MySQLdb.cursors import DictCursor 

然後我不再出現錯誤,我贏了甚至不得不mock.patch MySQLdb包裝:

# @mock.patch.object(MySQLdb, '__init__') 
class TestDatabase(unittest.TestCase): 
    ... 

不太滿意的解決方案。一般來說,我嘲笑生活在我的項目之外的課程(例如住在virtualenv)。我保持開放,所以希望有人能告訴我如何嘲笑這些類。

+0

您是否嘗試模擬MySQLdb.cursors.DictCursor與您在自定義類的setUp中使用的方式類似?因爲它看起來像你模擬MySQLdb .__ init__,然後期望找到正確不存在的MySQLdb.cursors – user3012759 2015-02-05 15:10:48

+0

不知道該怎麼做。 'patch_dict_cursor = mock.patch.object(DictCursor,'__init __')'這是否行得通? – Houman 2015-02-05 15:49:23

+0

認爲你需要更類似於此的東西:patch_dict_cursor = mock.patch(MySQLdb.cursors.DictCursor,spec = True) – user3012759 2015-02-05 15:56:48

回答

2

首先:確保你有Database.py

import MySQLdb.cursors 

否則你提到的錯誤將得到提升,即使你不修補什麼。如果你想再次檢查它,在__init__的頂部添加cur=MySQLdb.cursors.DictCursor並刪除所有修補程序:你會在新行中找到同樣的錯誤。如果您在嘗試指向MySQLdb.cursors.DictCursor之前在您的上下文中的某處加載了MySQLdb.cursors,則該錯誤將消失。如果你想知道,你有沒有看到這樣的錯誤之前是因爲在你的生產代碼,您在使用之前導入MySQLdb.cursorsCanonDatabase()

現在做一個測試,讓你的構造將通過和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) 

當然,如果你想打補丁create_connection每一個測試方法可以裝飾測試類。

相關問題