看這個網頁:http://www.toptal.com/python/an-introduction-to-mocking-in-python - 作者談論了Python中的模擬和修補,並給出了一個非常可靠的「真實世界」的例子。絆倒我的部分是理解單元測試框架如何工作知道哪個模擬對象被傳遞給哪個補丁。@ mock.patch如何知道每個模擬對象使用哪個參數?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import os.path
def rm(filename):
if os.path.isfile(filename):
os.remove(filename)
代碼示例很容易理解。硬件編碼依賴於OS庫/模塊。如果文件中刪除使用os.remove()
測試/模擬代碼如下存在使用os.path.isfile()
方法,如果是這樣,首先檢查:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import rm
import mock
import unittest
class RmTestCase(unittest.TestCase):
@mock.patch('mymodule.os.path')
@mock.patch('mymodule.os')
def test_rm(self, mock_os, mock_path):
# set up the mock
mock_path.isfile.return_value = False
rm("any path")
# test that the remove call was NOT called.
self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
# make the file 'exist'
mock_path.isfile.return_value = True
rm("any path")
mock_os.remove.assert_called_with("any path")
我猜什麼的困惑我的是,有2個@Patch電話和2個參數在測試中通過。單元測試框架如何知道mymodule.os.path
正在修補os.path
並且它被映射到mock_path
? mymodule.os.path
在哪裏定義?
(似乎有很多「神奇」的事情,我不跟隨它。)
好的,這解決了我的一半問題。 (實際上,我會說它是按倒序排列的,但是我在你鏈接的頁面上看到你的意思。)Next:Mock對象在哪裏創建?我看到我可以在測試中訪問它(因爲它是在我的裝飾器中傳遞的)。但是如果我想在明確的方法之外創建它,請在Setup()方法中說明呢?我將如何做到這一點? – Pretzel
當您按照您編寫它的方式使用修補程序時,它會自動爲您創建。還有另一個版本: @ mock.patch(「subprocess.check_output」,mock.MagicMock(return_value ='True')) def test_mockCheckOutput(self): 在這種情況下,你傳遞你自己的Mock對象,並在這個例子中,當你調用subprocess.check_output()時,它會返回'True' – eyalsn
隨意編輯你的答案,以便你的代碼顯示格式正確(以幫助任何其他人稍後閱讀。:)) – Pretzel