在python上模拟电子邮件负载

时间:2019-03-07 01:09:21

标签: python mocking python-unittest

我正在为某个功能编写单元测试,该功能应该获取电子邮件中的所有有效附件。我的函数具有以下行为:

def extract_attachments(local_file):
    email_file = open(local_file, "r")
    msg = email.message_from_file(email_file)        
    attchs = [x for x in msg.get_payload() if x.get_filename() is not None]
    for attch in attchs:
        filename = attch.get_filename()
        if filename not in VALID_ATTACHMENTS:
            raise Exception('Invalid attachment', filename)        
    return attchs

如何使此函数返回带有函数get_filename()的对象?

我正在尝试打补丁,但出现错误'list' object has no attribute 'get_payload'

@patch("mail_extractor.process_email.email")
@patch("builtins.open")
def test_extract_attachments(open, email):
    email.message_from_file.return_value = []
    email.get_payload.return_value = ['1.xml']
    result = process_email.extract_attachments('mock')
    assert len(result) == 1

2 个答案:

答案 0 :(得分:0)

您所描述的符号是特定于对象的,而您试图赋予它的是一种方法。您需要定义一个类:

class MyClass:
    def get_filename():
        # some logic

然后您就可以实例化对象:

x = MyClass()
x.get_filename()

这能回答您的问题吗?

答案 1 :(得分:0)

配置模拟的方式不太正确。 message_from_file()调用需要返回一条消息,而您正在返回一个列表-因此您将看到错误。

您应该设置一个模拟消息以及一个模拟附件,以便满足代码预期的调用。

例如:

@patch("mail_extractor.process_email.email")
@patch("builtins.open")
def test_extract_attachments(open, email):
    # Configure the mock message and its attachment
    mock_message = Mock()
    mock_attachment = Mock()
    mock_attachment.get_filename.return_value = '1.xml'
    mock_message.get_payload.return_value = [mock_attachment]

    # Configure message_from_file to return the mock message
    email.message_from_file.return_value = mock_message

    result = process_email.extract_attachments('mock')
    assert len(result) == 1