[英]How to use Mock.ANY with assert_called_with
I'm blocked. 我被阻止了。
I'm creating tests with nosetests and Mock. 我正在用nosetests和Mock创建测试。 It's very, very hard for me to understand how to do this properly.
我非常非常难以理解如何正确地做到这一点。 Here I want to make sure subprocess.check_output is called with the right parameters.
在这里,我想确保使用正确的参数调用subprocess.check_output。 I get this error message:
我收到此错误消息:
AssertionError: Expected call: check_output(['dscl', '/Search', 'read', '/Users/testuser', 'AuthenticationAuthority'], <ANY>)
Actual call: check_output(['dscl', '/Search', 'read', '/Users/testuser', 'AuthenticationAuthority'], stderr=-2)
Isn't Mock.ANY a wildcard ? Mock.ANY不是通配符吗? Did I misunderstand something ?
我误解了什么吗?
I'm not sensible, please tell me if I'm being stupid. 我不懂事,请告诉我,如果我是傻瓜。
def get_current_username():
"""Returns the user associated with the LaunchAgent running KerbMinder.py"""
return getpass.getuser()
@staticmethod
def get_principal_from_ad():
"""Returns the principal of the current user when computer is bound"""
import re
user_path = '/Users/' + get_current_username()
try:
output = subprocess.check_output(['dscl',
'/Search',
'read',
user_path,
'AuthenticationAuthority'],
stderr=subprocess.STDOUT)
match = re.search(r'[a-zA-Z0-9+_\-\.]+@[^;]+\.[A-Z]{2,}', output, re.IGNORECASE)
match = match.group()
except subprocess.CalledProcessError as error:
log_print("Can't find Principal from AD: " + str(error))
else:
log_print('Kerberos Principal is ' + match)
return match
@patch('KerbMinder2.get_current_username')
def test_ad_bound_notenabled(self, mock_get_current_username):
#https://github.com/nens/nensbuild/blob/master/nensbuild/tests.py
mock_get_current_username.return_value = "testuser"
_return_value = 'AuthenticationAuthority: ;ShadowHash;HASHLIST:' \
'<SMB-NT,CRAM-MD5,RECOVERABLE,SALTED-SHA512-PBKDF2> ' \
';LocalCachedUser;/Active Directory/TEST/test.com:testuser' \
':9A1F2D0C-B782-488A-80BA-CAC95AB6CAE9 ;Kerberosv5;;testuser@TEST.COM;' \
'TEST.COM; AuthenticationAuthority: ;Kerberosv5;;testuser@TEST.COM;TEST.COM; ' \
';NetLogon;testuser;TEST'
with patch('subprocess.check_output', return_value = _return_value) as check_output:
nose.tools.eq_(Principal.get_principal_from_ad(), "testuser@TEST.COM")
check_output.assert_called_with(['dscl',
'/Search',
'read',
'/Users/testuser',
'AuthenticationAuthority'],
ANY)
test_ad_bound_notenabled (test_KerbMinder2.TestPrincipal) ...
FAIL
Failure
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 331, in run
testMethod()
File "/Users/francois/venv-KerbMinder2/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "/Users/francois/Git/KerbMinder2/Library/Application Support/crankd/test_KerbMinder2.py", line 61, in test_ad_bound_notenabled
ANY)
File "/Users/francois/venv-KerbMinder2/lib/python2.7/site-packages/mock/mock.py", line 937, in assert_called_with
six.raise_from(AssertionError(_error_message(cause)), cause)
File "/Users/francois/venv-KerbMinder2/lib/python2.7/site-packages/six.py", line 718, in raise_from
raise value
AssertionError: Expected call: check_output(['dscl', '/Search', 'read', '/Users/testuser', 'AuthenticationAuthority'], <ANY>)
Actual call: check_output(['dscl', '/Search', 'read', '/Users/testuser', 'AuthenticationAuthority'], stderr=-2)
-------------------- >> begin captured stdout << ---------------------
Kerberos Principal is testuser@TEST.COM
--------------------- >> end captured stdout << ----------------------
AFAIK, you have to specify the keyword argument names to use the wildcard ANY. AFAIK,您必须指定关键字参数名称以使用通配符ANY。
Another option is to assert directly on the list of calls directly using mock_calls
: 另一种选择是直接使用
mock_calls
在调用列表上mock_calls
:
with patch('subprocess.check_output') as check_output:
... code to test here ...
func_name, args, kwargs = check_output.mock_calls[0]
assert func_name == 'check_output'
assert args == [list of positional args]
assert kwargs == {dict of keyword args} # in your case, you'd leave this out
Thanks to elias, here's the answer : 感谢伊莱亚斯,答案如下:
@patch('getpass.getuser')
def test_ad_bound_notenabled(self, mock_getpass_getuser):
# https://github.com/nens/nensbuild/blob/master/nensbuild/tests.py
# http://stackoverflow.com/questions/33214247/how-to-use-mock-any-with-assert-called-with
mock_getpass_getuser.return_value = "testuser"
_return_value = 'AuthenticationAuthority: ;ShadowHash;HASHLIST:' \
'<SMB-NT,CRAM-MD5,RECOVERABLE,SALTED-SHA512-PBKDF2> ' \
';LocalCachedUser;/Active Directory/TEST/test.com:testuser' \
':9A1F2D0C-B782-488A-80BA-CAC95AB6CAE9 ;Kerberosv5;;testuser@TEST.COM;' \
'TEST.COM; AuthenticationAuthority: ;Kerberosv5;;testuser@TEST.COM;TEST.COM; ' \
';NetLogon;testuser;TEST'
with patch('subprocess.check_output', return_value = _return_value) as check_output:
nose.tools.eq_(Principal.get_principal_from_ad(), "testuser@TEST.COM")
_, args, _ = check_output.mock_calls[0]
nose.tools.eq_(args, (['dscl',
'/Search',
'read',
'/Users/testuser',
'AuthenticationAuthority'],))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.