簡體   English   中英

無法使用來自 moto 的 mock_ses pytest AWS SES

[英]Cannot pytest AWS SES using mock_ses from moto

我正在努力為 AWS SES 編寫模擬測試。

以下是我要測試的文件aws_ses.py的內容-

def invoke_ses(send_args,ses_client):
    try:
        response = ses_client.send_templated_email(**send_args)
    except ClientError as e:
        logging.error(e)
        return e.value.response
    else:
        return response

以下是測試文件test_aws_ses.py的內容

from moto import mock_ses
from conftest import TEST_KWARGS
from emails.aws_ses import invoke_ses


def test_invoke_ses(aws_credentials, ses_client):

    # Issue 1
    assert invoke_ses(TEST_KWARGS, ses_client) == ClientError

    verification_response = ses_client.verify_domain_identity(Domain="test.com")
    assert verification_response['VerificationToken'] == "QTKknzFg2J4ygwa+XvHAxUl1hyHoY0gVfZdfjIedHZ0="
    assert verification_response['ResponseMetadata']['HTTPStatusCode'] == 200
    
    # Issue 2
    with pytest.raises(ClientError) as ex:
        invoke_ses(**TEST_KWARGS,ses_client)
    
    assert ex.value.response["Error"]["Code"] == "TemplateDoesNotExist"


test_invoke_ses方法的參數 - aws_credentialsses_client是 conftest.py 中定義的python固定裝置,如下所示 -

import os
import boto3
import pytest
from moto import mock_ses


DEFAULT_AWS_REGION = 'us-west-2'
SOURCE = 'superuser@test.com'
TEST_TEMPLATE_NAME = 'TEST_TEMPLATE_1'
TEST_EMAIL_RECIPIENTS = ['user1@test.com','user2@test.com','user3@test.com']
TEST_CC_LIST = ['to_cc1@test.com','to_cc2@test.com']
TEST_BCC_LIST = ['to_bcc1@test.com','to_bcc2@test.com']
TEST_SES_DESTINATION_WITH_LIMITED_EMAIL_RECIPIENTS={
            "ToAddresses": TEST_EMAIL_RECIPIENTS,
            "CcAddresses": TEST_CC_LIST,
            "BccAddresses": TEST_BCC_LIST,
        }
TEST_KWARGS = dict(
        Source=SOURCE,
        Destination=TEST_SES_DESTINATION_WITH_LIMITED_EMAIL_RECIPIENTS,
        Template=TEST_TEMPLATE_NAME,
        TemplateData='{"name": "test"}'
    )

@pytest.fixture
def aws_credentials():
    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
    os.environ["AWS_SECURITY_TOKEN"] = "testing"
    os.environ["AWS_SESSION_TOKEN"] = "testing"
    os.environ["AWS_DEFAULT_REGION"] = "us-east-1"


@mock_ses
@pytest.fixture
def ses_client():
    ses_client = boto3.client("ses", region_name=DEFAULT_AWS_REGION)
    yield ses_client

正如我在test_invoke_ses方法中評論的那樣,我目前面臨 2 個問題 -

第 1 期

assert invoke_ses(TEST_KWARGS, ses_client) == ClientError上面的語句拋出如下錯誤——

>       assert invoke_ses(TEST_KWARGS, ses_client) == ClientError
[CPython37-test] E       AssertionError: assert 'ClientError' == <class 'botoc....ClientError'>
[CPython37-test] E         +'ClientError'
[CPython37-test] E         -<class 'botocore.exceptions.ClientError'>
[CPython37-test] 
[CPython37-test] test/test_aws_ses.py:32: AssertionError

第 2 期

with pytest.raises(ClientError) as ex:
        ses_client.send_templated_email(**TEST_KWARGS)

上面的語句拋出以下錯誤 -

 >           invoke_ses(TEST_KWARGS, ses_client)
[CPython37-test] E           Failed: DID NOT RAISE <class 'botocore.exceptions.ClientError'>
[CPython37-test] 
[CPython37-test] test/test_aws_ses.py:39: Failed

如果我將invoke_ses(TEST_KWARGS, ses_client)替換為ses_client.send_templated_email(**TEST_KWARGS)所有測試用例都通過了。

我不明白為什么在調用相同的方法時 - 從另一個文件ses_client.send_templated_email中編寫的方法invoke_ses中的aws_ses.py失敗但直接調用它正在通過。

問題出在方法invoke_ses的響應中。 try 塊成功時收到的響應是字典。 但是當異常塊執行時,它拋出了一個我沒有捕獲的異常。 因此我修改了異常塊中的響應如下 -

原始方法

def invoke_ses(send_args,ses_client):
    try:
        response = ses_client.send_templated_email(**send_args)
    except ClientError as e:
        logging.error(e)
        return e.value.response
    else:
        return response

新方法

def invoke_ses(send_args, source, email_recipients, ses_client):
    try:
        response = ses_client.send_templated_email(**send_args)
        httpStatusCode = response['ResponseMetadata']['HTTPStatusCode']
        message_id = response['MessageId']
        logging.info(f"Sent templated mail {message_id} from {source} to Email Recipients SUCCESS")
    except ClientError as e:
        exception_string = str(e)
        logging.error(f"{str(e)}")
        return { 'Exception' : exception_string}
    else:
        return response

區別在於——

問題 1 解決方案 -

原始代碼

assert invoke_ses(TEST_KWARGS, ses_client) == ClientError

將上面的代碼更改為 -

response = invoke_ses(TEST_KWARGS, SOURCE, TEST_SES_DESTINATION_WITH_LIMITED_EMAIL_RECIPIENTS, ses_client)
    assert response['Exception'] == 'An error occurred (MessageRejected) when calling the SendTemplatedEmail operation: Email address not verified superuser@test.com'

問題 2 解決方案 -

原始代碼

with pytest.raises(ClientError) as ex:
        invoke_ses(**TEST_KWARGS,ses_client)
    
    assert ex.value.response["Error"]["Code"] == "TemplateDoesNotExist"

將上面的代碼更改為 -

response = invoke_ses(TEST_KWARGS, SOURCE, TEST_SES_DESTINATION_WITH_LIMITED_EMAIL_RECIPIENTS, ses_client)
    assert response['Exception'] == 'An error occurred (TemplateDoesNotExist) when calling the SendTemplatedEmail operation: Template (TEST_TEMPLATE_1) does not exist'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM