简单的例子.两种方法,一种叫另一种方法:
def method_a(arg):
some_data = method_b(arg)
def method_b(arg):
return some_data
Run Code Online (Sandbox Code Playgroud)
在Python中,我们可以def在另一个内部声明def.因此,如果method_b需要并且仅从中调用method_a,我应该method_b在内部声明method_a吗?像这样 :
def method_a(arg):
def method_b(arg):
return some_data
some_data = method_b
Run Code Online (Sandbox Code Playgroud)
或者我应该避免这样做?
如果我有这个功能,我应该怎么做用我自己的自定义版本替换内部函数?
def foo():
def bar():
# I want to change this
pass
# here starts a long list of functions I want to keep unchanged
def baz():
pass
Run Code Online (Sandbox Code Playgroud)
使用类可以轻松完成覆盖该方法.虽然,我无法弄清楚如何使用嵌套函数.更改foo为类(或其他任何内容)不是一个选项,因为它来自我无法修改的给定导入模块.
目前,我的 django 项目中有一个 google Drive API 客户端,可以按预期工作。
import unittest
from unittest import mock
DRIVE_API_VERSION = "v3"
DRIVE_API_SERVICE_NAME = "drive"
DRIVE_AUTHORIZED_USER_FILE = "path/to/secrets/json/file"
DRIVE_SCOPES = ['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file ', 'https://www.googleapis.com/auth/drive.appdata']
def construct_drive_service():
try:
drive_credentials = google.oauth2.credentials.Credentials.from_authorized_user_file(
DRIVE_AUTHORIZED_USER_FILE, scopes=DRIVE_SCOPES)
except FileNotFoundError:
print('Drive credentials not created')
pass
if drive_credentials:
return build(DRIVE_API_SERVICE_NAME, DRIVE_API_VERSION, credentials=drive_credentials, cache_discovery=False)
else:
return None
Run Code Online (Sandbox Code Playgroud)
现在我面临的挑战是为这个函数编写测试。但我不知道该使用什么策略。我试过这个
class TestAPICalls(unittest.TestCase):
@mock.patch('api_calls.google.oauth2.credentials', autospec=True)
def setUp(self, mocked_drive_cred):
self.mocked_drive_cred = mocked_drive_cred
@mock.patch('api_calls.DRIVE_AUTHORIZED_USER_FILE')
def test_drive_service_creation(self, mocked_file):
mocked_file.return_value = "some/file.json"
self.mocked_drive_cred.Credentials.return_value = mock.sentinel.Credentials
construct_drive_service()
self.mocked_drive_cred.Credentials.from_authorized_user_file.assert_called_with(mocked_file)
Run Code Online (Sandbox Code Playgroud)
但我的测试失败并出现以下错误
with io.open(filename, 'r', …Run Code Online (Sandbox Code Playgroud) 我有一个模块 utils.py,它有这个 run_cmd() 方法
def run_cmd(cmd):
pipe = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print(pipe.communicate())
print(pipe.returncode)
stdout, stderr = [stream.strip() for stream in pipe.communicate()]
output = ' - STDOUT: "%s"' % stdout if len(stdout) > 0 else ''
error = ' - STDERR: "%s"' % stdout if len(stderr) > 0 else ''
logger.debug("Running [{command}] returns: [{rc}]{output}{error}".format(
command=cmd,
rc=pipe.returncode,
output=output,
error=error))
return pipe.returncode, stdout, stderr
Run Code Online (Sandbox Code Playgroud)
我使用模拟和此链接stackoverflow作为参考编写了一个单元测试
@patch('subprocess.Popen')
@patch('utils.logger.debug')
def test_run_cmd(self, mock_popen, mock_log):
cmd = 'mock_command'
mocked_pipe = Mock()
attrs = {'communicate.return_value': …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Mock来测试从检索设置的函数返回的结果:
def apply_delta_to_date(original_date):
delta = MySettings.get_delta()
result_date = original_date + timedelta(delta)
return result_date
Run Code Online (Sandbox Code Playgroud)
在测试apply_delta_to_date函数时,我试图模拟调用MySettings.get_delta以模拟它返回特定结果:
class TestAppyDelta():
def setUp(self):
self.MySettings = Mock()
self.MySettings.get_delta = Mock(return_value=10)
def test_apply_delta(self):
result = apply_delta_to_date(today)
Run Code Online (Sandbox Code Playgroud)
问题是我无法“模拟”MySettings.get_delta()我真正想要测试的函数内部的函数调用。
我如何模拟我正在测试的函数中的内部函数返回的结果?
python ×4
mocking ×2
coding-style ×1
function ×1
nested ×1
overriding ×1
python-2.7 ×1
python-3.x ×1
subprocess ×1