You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MagicMock模拟smtplib.SMTP的send_message时断言调用失败

断言失败的原因及解决办法

核心问题

你把send_message的mock配置在了SMTP类对象上,但业务代码里实际调用的是SMTP实例对象的send_message方法,两者不是同一个对象,自然断言失败。

具体来说:

  • 测试代码里的mock_client是smtplib.SMTP这个类的mock,你配置的mock_client.send_message是类方法的mock
  • 业务代码中with smtplib.SMTP("localhost") as server创建了SMTP的实例server,实际调用的是server.send_message(msg)——也就是实例方法,和类的mock没关系

修正后的测试代码

你需要针对SMTP类实例的mock来配置send_message,也就是通过mock_client.return_value(它对应类实例化后的对象)来设置:

import email_sender as es
from unittest.mock import patch
import smtplib

def test_send_message_input_success() -> None:
    with patch("smtplib.SMTP", spec=smtplib.SMTP) as mock_client:
        # 获取SMTP实例的mock对象(对应业务代码里的server)
        mock_server = mock_client.return_value
        # 配置实例的send_message方法
        mock_server.send_message.return_value = None
        
        es.sendMessage()
        
        # 断言SMTP类被实例化过
        assert mock_client.called == True
        # 断言实例的send_message被调用
        assert mock_server.send_message.called == True

或者也可以用configure_mock直接配置实例方法:

mock_client.configure_mock(
    **{
        "return_value.send_message.return_value": None
    }
)

# 断言时改为检查实例方法的调用状态
assert mock_client.return_value.send_message.called == True

补充说明

mock_client作为类的mock,它的called属性为True,是因为业务代码里调用了smtplib.SMTP("localhost")——也就是实例化了这个类,所以类的mock被调用了,但类本身的send_message方法根本没被触发过,这就是第二个断言失败的原因。

内容的提问来源于stack exchange,提问作者N0000B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:30:59