Mockライブラリを使用してアプリケーションをテストしていますが、一部の関数が呼び出されなかったことをアサートしたいです。モックのドキュメントでは、mock.assert_called_with
やmock.assert_called_once_with
などのメソッドについて説明していますが、mock.assert_not_called
やモックの検証に関連する何か呼び出されないは見つかりませんでした。
私は次のようなもので行くことができますが、それはクールでもPythonicでもないようです:
def test_something:
# some actions
with patch('something') as my_var:
try:
# args are not important. func should never be called in this test
my_var.assert_called_with(some, args)
except AssertionError:
pass # this error being raised means it's ok
# other stuff
これを達成する方法はありますか?
助けてくれてありがとう:)
これはあなたのケースで機能するはずです。
assert not my_var.called, 'method should not have been called'
サンプル;
>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been
古い質問ですが、現在mock
ライブラリ(unittest.mockのバックポート)がassert_not_called
メソッドをサポートしていることを追加したいと思います。
アップグレードしてください。
pip install mock --upgrade
called
属性を確認できますが、アサーションが失敗した場合、次に知りたいことは何かabout予期しない呼び出しです。そのため、その情報を最初から表示されます。 unittest
を使用すると、代わりにcall_args_list
の内容を確認できます。
self.assertItemsEqual(my_var.call_args_list, [])
失敗すると、次のようなメッセージが表示されます。
AssertionError:要素数が等しくありませんでした: 最初の要素は0、2番目の要素は1:call( 'first argument'、4)
クラス継承unittest.TestCaseを使用してテストする場合、次のようなメソッドを使用できます。
同様の( pythonドキュメント で残りを見つけます)。
あなたの例では、mock_method.calledプロパティがFalse。これは、メソッドが呼び出されなかったことを意味します。
import unittest
from unittest import mock
import my_module
class A(unittest.TestCase):
def setUp(self):
self.message = "Method should not be called. Called {times} times!"
@mock.patch("my_module.method_to_mock")
def test(self, mock_method):
my_module.method_to_mock()
self.assertFalse(mock_method.called,
self.message.format(times=mock_method.call_count))
python >= 3.5
を使用すると、mock_object.assert_not_called()
を使用できます。
他の回答から判断すると、 @ rob-kennedy 以外の誰もcall_args_list
について話していません。
MagicMock.assert_called_with()
の正反対を実装できる強力なツールです
call_args_list
はcall
オブジェクトのリストです。各call
オブジェクトは、モックされた呼び出し可能オブジェクトで行われた呼び出しを表します。
>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.call_args_list
[]
>>> m(42)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42)]
>>> m(42, 30)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42), call(42, 30)]
call
オブジェクトの使用は簡単です。最初のコンポーネントが関連する呼び出しのすべての位置引数を含むタプルで、2番目のコンポーネントがキーワード引数の辞書である長さ2のタプルと比較できるためです。 。
>>> ((42,),) in m.call_args_list
True
>>> m(42, foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((42,), {'foo': 'bar'}) in m.call_args_list
True
>>> m(foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((), {'foo': 'bar'}) in m.call_args_list
True
したがって、OPの特定の問題に対処する方法は
def test_something():
with patch('something') as my_var:
assert ((some, args),) not in my_var.call_args_list
この方法では、モックされたcallableがMagicMock.called
を介して呼び出されたかどうかを確認する代わりに、特定の引数セットで呼び出されたかどうかを確認できることに注意してください。
それは便利です。リストを取得し、特定の条件を満たす場合にのみ、リストの各値に対して別の関数compute()
を呼び出す関数をテストするとします。
これでcompute
をモックでき、ある値で呼び出されたが、他の値では呼び出されなかったかどうかをテストできます。