use*_*716 8 python unit-testing mocking
我正在学习单元测试,但是我很难理解如何模拟单元测试的功能.我已经回顾了许多操作方法和示例,但这个概念没有足够的转让我在我的代码中使用它.我希望得到这个能够帮助我的实际代码示例.
在这种情况下,我试图模拟isTokenValid.
这是我想要模拟的示例代码.
<in library file>
import xmlrpc.client as xmlrpclib
class Library(object):
def function:
#...
AuthURL = 'https://example.com/xmlrpc/Auth'
auth_server = xmlrpclib.ServerProxy(AuthURL)
socket.setdefaulttimeout(20)
try:
if pull == 0:
valid = auth_server.isTokenValid(token)
#...
Run Code Online (Sandbox Code Playgroud)
在我的单元测试文件中
import library
class Tester(unittest.TestCase):
@patch('library.xmlrpclib.ServerProxy')
def test_xmlrpclib(self, fake_xmlrpclib):
assert 'something'
Run Code Online (Sandbox Code Playgroud)
我如何模拟'function'中列出的代码?令牌可以是任何数字作为字符串,有效将是一个int(1)
首先,你可以而且应该嘲笑xmlrpc.client.ServerProxy; 您的库xmlrpc.client作为新名称导入,但它仍然是相同的模块对象,因此xmlrpclib.ServerProxy在您的库中都会xmlrpc.client.ServerProxy导致同一个对象.
接下来,查看对象的使用方式,查找调用,(..)语法.您的库使用服务器代理,如下所示:
# a call to create an instance
auth_server = xmlrpclib.ServerProxy(AuthURL)
# on the instance, a call to another method
valid = auth_server.isTokenValid(token)
Run Code Online (Sandbox Code Playgroud)
所以这里有一个链,调用mock,然后返回值用于查找另一个也被调用的属性.嘲笑时,你需要寻找同一条链; 使用该Mock.return_value属性.默认情况下,在调用模拟时会返回新的模拟实例,但您也可以设置测试值.
因此,要测试代码,您需要影响auth_server.isTokenValid(token)返回的内容,并测试代码是否正常工作.您可能还想断言将正确的URL传递给ServerProxy实例.
为不同的结果创建单独的测试.也许令牌在一种情况下有效,在另一种情况下无效,并且您想要测试这两种情况:
class Tester(unittest.TestCase):
@patch('xmlrpc.client.ServerProxy')
def test_valid_token(self, mock_serverproxy):
# the ServerProxy(AuthURL) return value
mock_auth_server = mock_serverproxy.return_value
# configure a response for a valid token
mock_auth_server.isTokenValid.return_value = 1
# now run your library code
return_value = library.Library().function()
# and make test assertions
# about the server proxy
mock_serverproxy.assert_called_with('some_url')
# and about the auth_server.isTokenValid call
mock_auth_server.isTokenValid.assert_called_once()
# and if the result of the function is expected
self.assertEqual(return_value, 'expected return value')
@patch('xmlrpc.client.ServerProxy')
def test_invalid_token(self, mock_serverproxy):
# the ServerProxy(AuthURL) return value
mock_auth_server = mock_serverproxy.return_value
# configure a response; now testing for an invalid token instead
mock_auth_server.isTokenValid.return_value = 0
# now run your library code
return_value = library.Library().function()
# and make test assertions
# about the server proxy
mock_serverproxy.assert_called_with('some_url')
# and about the auth_server.isTokenValid call
mock_auth_server.isTokenValid.assert_called_once()
# and if the result of the function is expected
self.assertEqual(return_value, 'expected return value')
Run Code Online (Sandbox Code Playgroud)
有许多模拟属性可供使用,您可以稍微更改补丁装饰器的用法,如下所示:
class Tester(unittest.TestCase):
def test_xmlrpclib(self):
with patch('library.xmlrpclib.ServerProxy.isTokenValid') as isTokenValid:
self.assertEqual(isTokenValid.call_count, 0)
# your test code calling xmlrpclib
self.assertEqual(isTokenValid.call_count, 1)
token = isTokenValid.call_args[0] # assume this token is valid
self.assertEqual(isTokenValid.return_value, 1)
Run Code Online (Sandbox Code Playgroud)
您可以调整上面的代码以满足您的要求。