Как мы можем смоделировать несколько исключений в Pytest, Mock_Response?

Мы пересматриваем наш скрипт pytest в соответствии с ревизией родительского метода «исполнитель» — добавлена ​​логика повтора, чтобы повторить попытку 3 раза, пока не будет получен ответ и не возникнет ошибка при 4-й попытке.

Раньше мы тестировали исключение ошибки сокета следующим образом, теперь нам нужно вызвать это исключение после 3 повторных попыток (ниже код pytest обнаружил тестовую ошибку сейчас).

-- original code
def test_socketerror(monkeypatch, requests_mock):

    monkeypatch.setenv('ENV_ID', 'Local')
    requests_mock.post("http://localhost:8080/samplejob", exc=socket.error)

    with pytest.raises(CommunicationError) as ce:
        job_id = 'JOB_ID'
        executor = parentjob()
        executor.samplejob(job_id, None, None, None, None)
    assert str(ce.value.args[0]) == "same error message on parent method"

С другой стороны, мы можем пересмотреть другой тест повторной попытки, как и ожидалось, чтобы добавить mock_response с множественным ответом.

-- other test revise (seems working fine)
def test_retry(monkeypatch, requests_mock):

monkeypatch.setenv('ENV_ID', 'Local')
headers = {'content-type': 'application/json'}
mock_response = [
    {'json': {'status': None}, 'status_code': None},
    {'json': {'status': None}, 'status_code': None},
    {'json': {'status': None}, 'status_code': None},
    {'json': {'status': None}, 'status_code': None}
]
requests_mock.post("http://localhost:8080/samplejob", headers=headers, json=mock_response)

with pytest.raises(CommunicationError) as ce:
    job_id = 'JOB_ID'
    executor = parentjob()
    executor.samplejob(job_id, None, None, None, None)
assert str(ce.value.args[0]) == "same error message on parent method"

Но для исключения ошибки сокета нельзя применить несколько mock_response.

Позвольте мне также добавить родительскую работу:

class parent
    
    def parentjob(self, job_id, date, subject, fromDate, toDate):

        for error_count in range(self.error_retry_times):
            try:
                request_url = 'http://' + self.hostname + '/samplejob'
                headers = {'content-type': 'application/json'}
                response = requests.post(request_url, data=json.dumps(payload), timeout=self.timeout, headers=headers)
            except Timeout as te:
                error_message = 'access batch api timeout.jobId=%s, count=%d' % (job_id, error_count)
            except Exception as e:
                error_message = 'failed to access batch api.jobId=%s, count=%d' % (job_id, error_count)

            if response is None:
                time.sleep(self.error_retry_inerval)
            else:
                break

        if response is None or response.status_code != 202:
            error_message = "error message on parent method"
            raise CommunicationError(error_message)

        return response
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать макетное приспособление вот так:

def test_retry_exception(mocker):
    mocker.patch("parent_module_path.requests.post", side_effect = [Exception("first time"), Exception("second time"), Exception("third time"), Exception("forth time")])

    with pytest.raises(CommunicationError) as ce:
        job_id = 'JOB_ID'
        executor = parentjob()
        executor.samplejob(job_id, None, None, None, None)
    assert str(ce.value.args[0]) == "same error message on parent method"

Благодаря отличной подсказке @Peter K мне удалось создать и протестировать несколько исключений в таких запросах;

def test_socketerror(monkeypatch, requests_mock):
    monkeypatch.setenv('ENV_ID', 'Local')
    ***requests_mock.side_effect = (socket.error(),socket.error(),socket.error(),socket.error())
    requests_mock.post("http://localhost:8080/samplejob")***


with pytest.raises(CommunicationError) as ce:
    job_id = 'JOB_ID'
    executor = parentjob()
    executor.samplejob(job_id, None, None, None, None)
assert str(ce.value.args[0]) == "same error message on parent method"

Также это может быть применено для ошибки тайм-аута;

requests_mock.side_effect = (requests.exceptions.Timeout(),requests.exceptions.Timeout(),requests.exceptions.Timeout(),requests.exceptions.Timeout())

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

Другие вопросы по теме