Python 3.6 Beginner: зачем получать пустую ошибку AssertionError для assert_called_once_with (юнит-тест и макет) - PullRequest
0 голосов
/ 22 июня 2019

Привет, я новичок в Python, разработчик, и я пытаюсь запустить следующий смоделированный юнит-тест. Буду признателен за любую помощь, заранее спасибо!

У меня есть класс класса LeadsConsumer (модуля ведет_консумер), для которого я хочу выполнить модульное тестирование метода _process_lead.

from .helper import dynamo_helpers

class LeadsConsumer:

    def __init__(self):
        self._dynamodb = dynamo_helpers.Dynamo(AWS_RUNTIME_REGION, ENVIRONMENT, VERTICAL)

    def _process_lead(self, _lead):
        role_set = self._dynamodb.get_role_set(_lead.getPartner_id())
        if role_set is None:
            role_set = self._dynamodb.create_partner(_lead)
        if role_set['is-partner'] is True:
            return

        user = self._dynamodb.get_user(_lead.getEmail())
        if user is None:
            user = self._dynamodb.create_user(_lead)
        else:
            user = self._dynamodb.update_user(_lead)

И юнит-тест выглядит так:

class LeadsConsumerTest(TestCase):

    @mock.patch('src.leads_consumer.dynamo_helpers.Dynamo')
    def test_process_lead_new_lead(self, mock_dynamo_class):
        # given
        mock_dynamo_instance = mock_dynamo_class.return_value
        mock_dynamo_instance.get_role_set.return_value = None
        mock_dynamo_instance.create_partner.return_value = self._given_role_set(False)
        mock_dynamo_instance.get_user.return_value = None
        mock_dynamo_instance.create_user.return_value = None

        _leads_consumer = LeadsConsumer()
        _lead = self._given_lead(False)

        # when
        _leads_consumer._process_lead(_lead)

        # then
        assert mock_dynamo_instance.get_role_set.assert_called_once_with(_lead.getPartner_id())
        assert mock_dynamo_instance.create_partner.assert_called_once()
        assert mock_dynamo_instance.get_user.assert_called_once()
        assert mock_dynamo_instance.create_user.assert_called_once_with(_lead)

Когда я запускаю этот тест, я получаю следующую ошибку AssertionError:

in test_process_lead_new_lead
assert mock_dynamo_instance.get_role_set.assert_called_once_with(_lead.getPartner_id())
AssertionError

Пустая ошибка AssertionError (без каких-либо объяснений, что не так) меня немного смущает. Если я изменю

assert mock_dynamo_instance.get_role_set.assert_called_once_with(_lead.getPartner_id())

до

assert mock_dynamo_instance.get_role_set.assert_called_once_with("foobar", _lead.getPartner_id())

Я получаю

AssertionError: Expected call: get_role_set('foobar', '1000000')
Actual call: get_role_set('1000000')

Это, как я понимаю, отчасти ожидалось. Но тогда почему я получаю AssertionError, если я покидаю тест, как в оригинале выше? Я не понимаю этого. Модифицированный тест показывает, что метод get_role_set был вызван с ('foobar', '1000000'). Так что, если я опущу 'foobar', почему тест не пройдет без ошибки? (На самом деле я получаю ту же ошибку для последней строки теста, если закомментирую другие утверждения.)

Может кто-нибудь сказать мне, что я здесь делаю не так? Также были бы высоко оценены подсказки о других недостатках в коде новобранца. Спасибо.

1 Ответ

1 голос
/ 22 июня 2019

Вы путаете два синтаксиса здесь. assert - это команда, которую вы используете с нормальными выражениями; оно вызывает исключение, если выражение неверно.

assert_called_once_with - это метод, предоставленный объектом Mock, который снова вызывает AssertionError, если он не работает, но возвращает None в противном случае.

Итак, у вас здесь два утверждения. Результатом вызова assert_called_once_with является None, что, конечно, ложно; поэтому вы получаете AssertionError из оператора assert.

Решение состоит в том, чтобы просто удалить все ключевые слова assert и просто оставить вызовы методов assert_called_once и assert_called_once_with.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...