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

使用unittest @patch mock类中self.attribute.savefig测试失败,求原因

测试MyClass.invoke()时断言savefig调用失败的原因

待测试代码(file1.py)

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk


class MyClass:
    
    def __init__(self):
        pass

    def to_test(self):
        if hasattr(self, 'attribute'): # self.attribute由其他方法定义,测试中不想调用该方法
            filepath= 'the_file_path'
            self.attribute.savefig(filepath)

    def invoke(self): # GUI按钮触发的简化命令
        self.to_test()

测试代码

import unittest
from unittest.mock import patch, MagicMock
import sys
sys.path.append('path to directory')
from file1 import MyClass


@patch('file1.plt.savefig')
def test(mock_save):
    myclass = MyClass()
    myclass.attribute = MagicMock()
    myclass.invoke()
    assert mock_save.call_count == 1

运行错误

E       AssertionError: assert 0 == 1
E        +  where 0 = <MagicMock name='savefig' id='4471947984'>.call_count

错误原因及修正

原因

你mock了完全无关的对象:

  • 待测试代码里实际调用的是self.attribute.savefig(),这个savefig是你手动赋值给myclass.attribute的MagicMock实例的方法
  • 但测试代码中patch的是file1.plt.savefig,这是matplotlib.pyplot模块的全局函数,和代码里调用的对象没有任何关联,所以mock的mock_save从来不会被触发,call_count自然为0。

修正方案

直接检查你创建的myclass.attribute的savefig方法调用情况,无需patch plt.savefig:

def test():
    myclass = MyClass()
    myclass.attribute = MagicMock()
    myclass.invoke()
    # 方式1:检查调用次数和参数
    myclass.attribute.savefig.assert_called_once_with('the_file_path')
    # 方式2:仅检查调用次数
    assert myclass.attribute.savefig.call_count == 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 23:32:43