Атакующие атрибуты с помощью @patch decorator - PullRequest
0 голосов
/ 28 апреля 2018

Я борюсь с насмешливыми атрибутами в моих тестах Python. Функция, которую я пытаюсь протестировать, продолжает давать сбой, потому что макет, вероятно, возвращает правильное значение, но это неправильный тип (Должно быть строка, а вместо этого MagicMock.

Я нашел этот ответ и понимаю, что мне нужно использовать PropertyMock. Но я не могу заставить его работать ни с менеджером контекста, ни с использованием декоратора @patch. Макет атрибутов в Python mock?

Вот мой тест:

 @patch('keys.views.requests.post')
 @patch('keys.views.requests.Response.text', new_callable=PropertyMock)
 def test_shows_message_when_receives_error(self, mock_response_text     ,mock_post):

     expected_error = escape(MESSAGE)
     data_to_be_received = json.dumps({
         "message":"Bad Request",
         "errors":[{
             "resource":"Application",
             "field":"client_id",
             "code":"invalid"
         }]
     })
     mock_response_text.return_value = data_to_be_received

     response = self.client.get('/users/tokenexchange?state=&code=abc123')

     self.assertContains(response, expected_error)

И код, который я тестирую:

def token_exchange(request):
    parameters = {'client_id': '##', 'client_secret': '##', 'code': code}

    response = requests.post('https://www.strava.com/oauth/token', parameters)
    data_received = json.loads(response.text)

    if 'errors' not in data_received:
        return HttpResponse(response.text)
     else:
         return render(request, 'home.html', {'error': STRAVA_AUTH_ERROR})

Ошибка, которую я продолжаю получать:

File "##", line 66, in token_exchange
    data_received = json.loads(response.text)

TypeError: the JSON object must be str, bytes or bytearray, not 'MagicMock'

Спасибо за ваши ответы !!!

1 Ответ

0 голосов
/ 29 апреля 2018

keys.views.requests.Response.text весьма вероятно instance variable, который не может и не должен подвергаться насмешкам с использованием PorpertyMock

Вот цитата из документации:

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

https://docs.python.org/2/tutorial/classes.html

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

Как смоделировать переменную класса python instance_variable?

У меня было решение, которое скопировано откуда-то, оно работало слишком утомительно:

Python макет атрибута базового класса

В вашем конкретном случае имитируйте класс Response вместо text instance

@patch('keys.views.requests.post')
@patch('keys.views.requests.Response')
def test_shows_message_when_receives_error(self, mock_response ,mock_post):
    mock_post.return_value = None # mock the func
    mock_response.text = mock.Mock(text=data_to_be_received).text
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...