【问题标题】:mock xmlrpc.client method python模拟 xmlrpc.client 方法 python
【发布时间】:2017-01-04 05:54:50
【问题描述】:

我正在学习单元测试,但是我很难理解如何模拟单元测试的函数。我已经查看了许多操作指南和示例,但是这个概念并没有足够的转移到我在我的代码中使用它。我希望在我拥有的实际代码示例中使用它会有所帮助。

在这种情况下,我试图模拟 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)
        #...

在我的单元测试文件中有

import library

class Tester(unittest.TestCase):
    @patch('library.xmlrpclib.ServerProxy')
    def test_xmlrpclib(self, fake_xmlrpclib):
        assert 'something'

如何模拟“函数”中列出的代码?令牌可以是字符串形式的任何数字,有效的是 int(1)

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    首先,你可以并且应该模拟xmlrpc.client.ServerProxy;您的库将 xmlrpc.client 作为新名称导入,但它仍然是同一个模块对象,因此您的库中的 xmlrpclib.ServerProxyxmlrpc.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)
    

    所以这里有一个链,调用mock的地方,然后使用返回值来查找另一个也被调用的属性。嘲笑时,您需要寻找相同的链条;为此使用Mock.return_value attribute。默认情况下,调用 mock 时会返回一个新的 mock 实例,但您也可以设置测试值。

    所以要测试您的代码,您需要影响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')
    

    【讨论】:

      【解决方案2】:

      有很多mock attributes可以使用,你可以稍微改变一下你的补丁装饰器用法如下:

      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)
      

      您可以调整上面的代码以满足您的要求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2019-11-24
        • 1970-01-01
        相关资源
        最近更新 更多