计算器GUI等号按钮单元测试触发AssertionError如何修正?
报错原因
- 你的
btneq_clicked函数没有设置返回值,Python中无显式return的函数默认返回None,直接拿返回值和3做断言必然触发AssertionError: None != 3 - 该函数的所有逻辑都依赖全局的
disp(tkinter输入框组件),输入读取、结果写入都是直接操作disp组件,不会把计算结果返回给调用方 - 测试时的传参逻辑错误:
btneq_clicked的*args是用来接收GUI点击事件的占位参数,不需要手动传入计算后的值,函数会主动从disp中读取表达式
修正方案
有两种可选方案,推荐第一种不需要修改原有业务代码:
方案1:用Mock模拟disp组件做单元测试
借助unittest自带的mock模块模拟disp对象,验证函数对disp的操作是否符合预期,示例代码如下:
import unittest from unittest.mock import Mock, patch # 请将此处替换为你自己的模块导入路径,假设原业务代码写在calc.py中 from calc import btneq_clicked class TestCalc(unittest.TestCase): def test_plus_correct(self): # 构造模拟的disp对象 mock_disp = Mock() # 设定disp.get()的返回值为我们要测试的计算表达式 mock_disp.get.return_value = "1 + 2" # 将业务代码中依赖的全局disp替换为模拟对象 import calc calc.disp = mock_disp # 直接调用等号点击函数,不需要传参 btneq_clicked() # 验证disp.insert方法被调用时传入了正确的计算结果3 mock_disp.insert.assert_called_once_with(0, 3) # 可选:验证清空输入框的操作也正常执行 mock_disp.delete.assert_called_once_with(0, Mock.ANY) def test_invalid_expression(self): # 异常场景测试:验证非法表达式会触发报错弹窗 mock_disp = Mock() mock_disp.get.return_value = "1 + * 3" import calc calc.disp = mock_disp with patch('calc.tkinter.messagebox.showerror') as mock_error: btneq_clicked() # 验证弹窗按预期触发,参数正确 mock_error.assert_called_once_with("Value Error", "Check your values and operators") if __name__ == '__main__': unittest.main()
方案2:拆分业务逻辑提升可测试性(可选)
如果愿意调整原有代码,把纯计算逻辑和GUI交互逻辑解耦,后续测试会更简单,不需要做任何mock:
调整后的业务代码
# 纯计算逻辑,无GUI依赖,可直接测试 def calc_expression(expr: str): try: return eval(expr), None except: return None, "invalid expression" # GUI交互逻辑,只做组件操作 def btneq_clicked(*args): res, err = calc_expression(disp.get()) if err: tkinter.messagebox.showerror("Value Error", "Check your values and operators") return disp.delete(0, END) disp.insert(0, res)
对应的测试代码
def test_plus(self): res, err = calc_expression("1 + 2") self.assertEqual(res, 3) self.assertIsNone(err)
内容的提问来源于stack exchange,提问作者Yosh
相关产品推荐
相关产品推荐

