Патч для Pytest mocker boto3.resource работает только для первого из нескольких методов Pytest - PullRequest
0 голосов
/ 19 марта 2020

ЦЕЛЬ

Макет boto3.resource('s3'), чтобы pytest мог высмеивать методы S3-корзины.

ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ

  1. mocker.patch('boto3.resource') позволят смоделировать методы корзины s3.
  2. Можно использовать макет, созданный на шаге # 1 в методе множественного юнит-теста и будет работать согласованно.

АКТУАЛЬНЫЕ РЕЗУЛЬТАТЫ

mocker.patch('boto3.resource') работает только так, как ожидается в первом методе юнит-теста. Во втором методе unittest он не работает.

ПРОИЗВОДСТВЕННЫЙ КОД ПРОИЗВОДСТВА

#prod.py

import boto3 as boto3

s3 = boto3.resource('s3')


def lambda_handler(event, context):
    bucket = s3.Bucket('prod_bucket')
    items = bucket.objects.all()
    size = sum(1 for _ in items)
    print(f'Size: {size}')
    return {
        'statusCode': 200
    }

SAMPLE PYTEST CODE


#test_prod.py

import pytest


@pytest.fixture
def event():
    return {}


@pytest.fixture
def context():
    return None


@pytest.fixture
def mocked_boto3_resource(mocker):
    mocked_boto3_resource = mocker.patch('boto3.resource')
    return mocked_boto3_resource


def test_lambda_handler__1(mocked_boto3_resource):
    mocked_boto3_resource.return_value.Bucket.return_value.objects.all.return_value.__iter__.return_value = \
        iter(['1', '2'])
    from prod import prod
    actual = prod.lambda_handler(event, context)
    print(actual)


def test_lambda_handler__2(mocked_boto3_resource):
    mocked_boto3_resource.return_value.Bucket.return_value.objects.all.return_value.__iter__.return_value = \
        iter(['1', '2', '3', '4'])
    from prod import prod
    actual = prod.lambda_handler(event, context)
    print(actual)

ВЫХОД КОНСОЛИ PYTEST

============================= test session starts =============================
platform win32 -- Python 3.7.6, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- 
plugins: mock-2.0.0
collecting ... collected 2 items

test_prod.py::test_lambda_handler__1 PASSED                              [ 50%]Size: 2
{'statusCode': 200}

test_prod.py::test_lambda_handler__2 PASSED                              [100%]Size: 0
{'statusCode': 200}
============================== 2 passed in 0.22s ==============================

Примечание Size: 2 для первого теста и Size: 0 для второго теста. Я бы ожидал Size: 4 для второго теста.

...