[英]Mocking two functions with patch for a unit test
我有一個 function 我想單元測試包含調用另外兩個函數。 我不確定如何使用補丁同時正確地模擬這兩個功能。 我在下面提供了一個例子來說明我的意思。 當我運行 nosetests 時,測試通過了,但我覺得必須有一種更簡潔的方法來做到這一點,我並不真正理解關於 f.close() 的文章......
目錄結構如下所示:
program/
program/
data.py
tests/
data_test.py
數據.py:
import cPickle
def write_out(file_path, data):
f = open(file_path, 'wb')
cPickle.dump(data, f)
f.close()
數據測試.py:
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
mock_open = MagicMock()
mock_pickle = MagicMock()
f_mock = MagicMock()
with patch('__builtin__.open', mock_open):
f = mock_open.return_value
f.method.return_value = path
with patch('cPickle.dump', mock_pickle):
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
f.close.assert_any_call()
mock_pickle.assert_called_once_with('data', f)
結果:
$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
您可以使用修補程序裝飾器簡化測試並將其嵌套(默認情況下它們是MagicMock
對象):
@patch('cPickle.dump')
@patch('__builtin__.open')
def test_write_out(mock_open, mock_pickle):
path = '~/collection'
f = mock_open.return_value
f.method.return_value = path
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
mock_pickle.assert_called_once_with('data', f)
f.close.assert_any_call()
對MagicMock
實例的調用返回一個新的MagicMock
實例,因此您可以檢查返回的值是否像任何其他模擬對象一樣被調用。 在這種情況下, f
是名為'open()'
的MagicMock
(嘗試打印f
)。
除了響應@Matti John之外,您還可以在函數test_write_out
使用patch
:
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
with patch('__builtin__.open') as mock_open, \
patch('cPickle.dump') as mock_pickle:
f = mock_open.return_value
...
從 Python 3.10 開始,您可以像這樣使用帶括號的上下文管理器
from unittest.mock import patch
def test_write_out():
with (
patch('cPickle.dump'),
patch('__builtin__.open') as open_mock, # example of using `as`
):
yield
這是一個關於如何使用mock在create_collection
函數中測試引發ConflictError
的簡單示例:
import os
from unittest import TestCase
from mock import patch
from ..program.data import ConflictError, create_collection
class TestCreateCollection(TestCase):
def test_path_exists(self):
with patch.object(os.path, 'exists') as mock_method:
mock_method.return_value = True
self.assertRaises(ConflictError, create_collection, 'test')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.