assertRaises的单元测试问题

18 投票
2 回答
9308 浏览
提问于 2025-04-16 01:40

我正在尝试测试一个异常情况。

我有:

def test_set_catch_status_exception(self):
    mro = self.mro
    NEW_STATUS = 'No such status'
    self.assertRaises(ValueError,mro.setStatus(NEW_STATUS))

但是我遇到了以下错误:

======================================================================
ERROR: test_set_catch_status_exception (__main__.TestManagementReviewGoalGetters)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_ManagementReviewObjective.py", line 68, in test_set_catch_status_exception
    self.assertRaises(ValueError,mro.setStatus(NEW_STATUS))
  File "/Users/eric/Dropbox/ManagementReview.py", line 277, in setStatus
    raise ValueError('%s is not in the list of allowed statuses: %s' % (status,LIST_OF_STATUSES))
ValueError: No such status is not in the list of allowed statuses: ['Concern or Delay', 'On Track', 'Off Track/Needs Attention']

----------------------------------------------------------------------

谢谢!

2 个回答

1

如果你在使用 factory boy 这个工具,要小心哦!这个工具不允许错误被抛到检查的层面上,这样的话检查总是会失败。

41

self.assertRaises 这个东西需要一个函数 mro.setStatus,后面可以跟任意数量的参数,这里只需要一个 NEW_STATUSself.assertRaises 会把这些参数组合成一个函数调用,也就是 mro.setStatus(NEW_STATUS),然后放在一个 try...except 结构里,这样如果出现 ValueError 错误,它就能捕捉到并记录下来。

如果把 mro.setStatus(NEW_STATUS) 直接作为参数传给 self.assertRaises,那么 ValueError 错误会在 self.assertRaises 还没来得及捕捉之前就发生了。

所以解决办法就是把括号改成逗号:

self.assertRaises(ValueError,mro.setStatus,NEW_STATUS)

撰写回答