繁体   English   中英

Python-Monkey Patching奇怪的错误

[英]Python - Monkey Patching weird bug

我的假模拟课程如下所示:

class FakeResponse:
    method = None               # 
    url = None                  # static class variables

    def __init__(self, method, url, data):#, response):
        self.status_code = 200       # always return 200 OK
        FakeResponse.method = method # 
        FakeResponse.url = url       #

    @staticmethod
    def check(method, url, values):
       """ checks method and URL.      
       """
       print "url fake: ", FakeResponse.url
       assert FakeResponse.method == method
       assert FakeResponse.url == url

我有一个适用于所有测试用例的装饰器:

@pytest.fixture(autouse=True)
def no_requests(monkeypatch):
    monkeypatch.setattr('haas.cli.do_put',
                    lambda url,data: FakeResponse('PUT', url, data))
    monkeypatch.setattr("haas.cli.do_post",
                    lambda url,data: FakeResponse('POST', url, data))
    monkeypatch.setattr("haas.cli.do_delete",
                    lambda url: FakeResponse('DELETE', url, None))

我正在使用Py.test来测试代码。

一些示例测试用例是:

class Test:
    #test case passes
    def test_node_connect_network(self):
       cli.node_connect_network('node-99','eth0','hammernet')
       FakeResponse.check('POST','http://abc:5000/node/node-99/nic/eth0/connect_network',
                        {'network':'hammernet'})

    # test case fails
    def test_port_register(self):
        cli.port_register('1') # This make a indirect REST call to the original API
        FakeResponse.check('PUT','http://abc:5000/port/1', None)

    # test case fails
    def test_port_delete(self):
        cli.port_delete('port', 1)
        FakeResponse.check('DELETE','http://abc:5000/port/1', None)  

我得到的示例错误消息:

    method = 'PUT', url = 'http://abc:5000/port/1', values = None

    @staticmethod
    def check(method, url, values):
        """ checks method and URL.
           'values': if None, verifies no data was sent.
           if list of (name,value) pairs, verifies that each pair is in 'values'
        """
        print "url fake: ", FakeResponse.url
>       assert FakeResponse.method == method
E       assert 'POST' == 'PUT'
E         - POST
E         + PUT
haas/tests/unit/cli_v1.py:54: AssertionError
--------------------------------------------- Captured stdout call -------------------------------------
port_register <port>
Register a <port> on a switch
url fake:  http://abc:5000/node/node-99/nic/eth0/connect_network
--------------------------------------------- Captured stderr call -------------------------------------
Wrong number of arguements.  Usage: 

而如果我考虑检查功能采用“ self”参数并且不使用@staticmethod的情况下,以下面的方式调用第二个测试用例,则该测试用例可以工作:

def test_port_register(self):
    cli.port_register('1')
    fp = FakeResponse('PUT','http://abc:5000/port/1', None) #Create a FakeResponse class instance
    fp.check('PUT','http://abc:5000/port/1', None) # Just call the check function with the same                                                          
                                                     arguments

问题:

  • 使用猴子补丁和@staticmethod是否有任何副作用
  • 下一个函数调用中如何使用为上一个测试函数定义的url。
  • 不应有一个范围论据来禁止上述不必要的行为。
  • 有没有更好的方法来修补猴子。

对不起,很长的帖子,我已经尝试解决了一个星期,并希望对其他程序员有所了解。

问题是没有其中一项功能的正确签名。 通过更改作为空字典{}传递给MonkeyPatch函数的参数而不是特定于我的代码的'None'值来解决。

我最初遇到此问题的原因是,当参数传递给port_register本身时,当前函数的调用(cli.port_register)失败,因此它从先前的状态中获取参数值并使用FakeResponse进行断言呼叫。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM