Mocking AWS session.Session() got AttributeError: 'function' object has no attribute 'call_count'?

Mocking AWS session.Session() got AttributeError: 'function' object has no attribute 'call_count'?

我需要为以下 class 函数编写单元测试,returns AWS 的 EC2 实例将被测试。

class C:
    def f(cls, session, filters):
            # ....
            instances = session.resource('ec2').instances.filter(Filters=filters)
            # ....
            return instances

我想测试 session.resource('ec2').instances.filter() 是否使用参数 Filters=filters 调用。

import boto3
import boto3.session
import pytest
from moto import mock_ec2

@mock_ec2
def test_get_nodes():
    '''Test get node'''
    session = boto3.session.Session(region_name='')
    filters = None
    C.f(session, filters)
    assert session.resource('ec2').instances.filter.call_count == 1

但是测试出现如下错误?

>           raise ValueError("Invalid endpoint: %s" % endpoint_url)
E           ValueError: Invalid endpoint: https://ec2..amazonaws.com

我不想让测试函数实际连接到 AWS 控制台。无论如何,在我为 region_name 设置了正确的值后出现了以下错误:

>       assert session.resource('ec2').instances.filter.call_count == 1
E       AttributeError: 'function' object has no attribute 'call_count'

这里没有设置地区:

session = boto3.session.Session(region_name='')

尝试填写区域。

您似乎在尝试将传统模拟方法(例如测试调用次数、捕获参数等)与 Moto 结合使用。但是 Moto 不会公开任何这些信息。

Moto 更像是一个 in-memory AWS 实例。这意味着您可以使用任何(支持的)boto3 请求,Moto 将拦截该请求并像 AWS 一样运行 - 但实际上不会发出请求(并产生任何费用)。

传统的 Moto 测试用例(在 pseudo-case 中)如下所示:

assert len(session.resource('ec2').instances) == 0
ec2_client.run_instances(..)
assert len(session.resource('ec2').instances) == 2
assert len(session.resource('ec2').instances.filter) == 1

None 其中检查方法是否被调用 - 它使用 boto3-requests 来验证之前的 boto3-requests 是否成功,就像您正在针对 AWS 本身编写集成测试一样。

编辑:
如果您担心向 AWS 本身发出请求,则值得设置虚拟环境变量以在测试期间重置您的访问 key/secret 密钥。
参见 http://docs.getmoto.org/en/latest/docs/getting_started.html#recommended-usage

也可以使用 nonexistent-region,更省心。

os.environ["MOTO_ALLOW_NONEXISTENT_REGION"] = True
os.environ["AWS_DEFAULT_REGION"] = "antarctica"

在此处查看常见问题解答: http://docs.getmoto.org/en/latest/docs/faq.html#can-i-mock-the-default-aws-region