あなたは定義することができるassertNotRaisesの元の実装の約90%再利用することでassertRaises中unittestのモジュール。このアプローチでは、assertNotRaisesその逆の障害状態を除いて、と同じように動作するメソッドが作成されassertRaisesます。
TLDRとライブデモ
assertNotRaisesメソッドを追加するのは驚くほど簡単であることがわかりましたunittest.TestCase(この回答を書くのに、コードの場合と比べて約4倍の時間がかかりました)。ここには、assertNotRaisesメソッドの動作のライブデモです。と同様にassertRaises、callableとargsをに渡すかassertNotRaises、withステートメントで使用できます。ライブデモには、assertNotRaises意図したとおりに機能することを示すテストケースが含まれています。
細部
assertRaisesin の実装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メソッドを使用できるようになります。