2014-11-18 2 views
0

Моего Поддельный Мок класс выглядит следующим образом:Python - Обезьяна заплаты странно ошибка

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 для предыдущей функции тестирования используется при следующем вызове функции.
  • Не должно быть определения аргумента, чтобы запретить вышеупомянутое нежелательное поведение.
  • Есть ли лучший способ для патча обезьяны.

Извините за длинный пост, я пытаюсь разрешить это в течение недели и хотел найти перспективу других программистов.

+0

Непонятно, что вы ожидаете отсюда. Вы явно используете атрибуты класса, поэтому я не понимаю, почему вы удивляетесь, когда они сохраняются между экземплярами: вот и все атрибуты класса. –

+0

Есть ли лучший способ выполнить поддельный тест. Внутренне атрибуты класса FakeResponse используются в другом модуле для выполнения некоторых вычислений. – abhi09

+0

Попробуйте отладить 'cli.port_register ('1')' и проверить, не вызывает ли запрос 'POST' после' PUT'. Ваш код не красив, но он должен работать ... но только проверять * последний * вызов на 'FakeResponse()' –

ответ

2

Проблема не имела правильной подписи для одной из функций. Это было разрешено путем изменения аргумента, переданного функции MonkeyPatch, в виде пустого словаря {} вместо значения «Нет», которое является специфическим для моего кода.

Причина, по которой я изначально сталкивался с проблемой, заключалась в том, что вызов текущей функции (cli.port_register) терпел неудачу, когда параметры, переданные в port_register, поэтому он взял значения аргументов из предыдущего состояния и выполнил утвердить с помощью вызова FakeResponse.

Смежные вопросы