あなたは定義することができるassertNotRaises
の元の実装の約90%再利用することでassertRaises
中unittest
のモジュール。このアプローチでは、assertNotRaises
その逆の障害状態を除いて、と同じように動作するメソッドが作成されassertRaises
ます。
TLDRとライブデモ
assertNotRaises
メソッドを追加するのは驚くほど簡単であることがわかりましたunittest.TestCase
(この回答を書くのに、コードの場合と比べて約4倍の時間がかかりました)。ここには、assertNotRaises
メソッドの動作のライブデモです。と同様にassertRaises
、callableとargsをに渡すかassertNotRaises
、with
ステートメントで使用できます。ライブデモには、assertNotRaises
意図したとおりに機能することを示すテストケースが含まれています。
細部
assertRaises
in の実装unittest
はかなり複雑ですが、少し巧妙なサブクラス化によって、その障害状態をオーバーライドして元に戻すことができます。
assertRaises
基本的にunittest.case._AssertRaisesContext
クラスのインスタンスを作成して返す短いメソッドです(unittest.case
モジュールでの定義を参照)。独自に定義できます_AssertNotRaisesContext
メソッドをサブクラス化_AssertRaisesContext
してオーバーライドによりクラス__exit__
。
import traceback
from unittest.case import _AssertRaisesContext
class _AssertNotRaisesContext(_AssertRaisesContext):
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
self.exception = exc_value.with_traceback(None)
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} raised".format(exc_name))
else:
traceback.clear_frames(tb)
return True
通常、テストケースクラスは、クラスから継承させることで定義します。 TestCase
。代わりにサブクラスから継承する場合MyTestCase
:
class MyTestCase(unittest.TestCase):
def assertNotRaises(self, expected_exception, *args, **kwargs):
context = _AssertNotRaisesContext(expected_exception, self)
try:
return context.handle('assertNotRaises', args, kwargs)
finally:
context = None
これで、すべてのテストケースでassertNotRaises
メソッドを使用できるようになります。