164

Mockライブラリを使用してアプリケーションをテストしていますが、一部の関数が呼び出されなかったことを表明したいと思います。mock.assert_called_withモックドキュメントはとのようなメソッドについて話しますが、モックが呼び出されなかったことを確認するためのようなものや関連するものmock.assert_called_once_withは見つかりませんでした。mock.assert_not_called

私は次のようなもので行くことができますが、それはクールでもパイソンでもないようです:

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

これを達成する方法はありますか?

4

7 に答える 7

173

これはあなたのケースでうまくいくはずです。

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
于 2012-08-29T22:12:30.073 に答える
93

mock古い質問ですが、現在ライブラリ(unittest.mockのバックポート)がassert_not_calledメソッドをサポートしていることを追加したいと思います。

アップグレードするだけです。

pip install mock --upgrade

于 2017-01-10T12:12:00.227 に答える
31

属性を確認することはできcalledますが、アサーションが失敗した場合、次に知りたいのは予期しない呼び出しに関することなので、その情報を最初から表示するように調整することもできます。を使用して、代わりにunittestの内容を確認できます。call_args_list

self.assertItemsEqual(my_var.call_args_list, [])

失敗すると、次のようなメッセージが表示されます。

AssertionError:要素数が等しくありませんでした:
最初は0、2番目は1:call('最初の引数'、4)
于 2013-07-02T17:48:24.983 に答える
31

で使用python >= 3.5できますmock_object.assert_not_called()

于 2018-12-07T13:43:19.270 に答える
19

クラスを使用してテストする場合、unittest.TestCaseを継承し、次のようなメソッドを使用できます。

  • assertTrue
  • assertFalse
  • assertEqual

および同様のもの(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))
于 2015-06-24T21:48:17.690 に答える
2

他の回答から判断すると、 @rob-kennedy以外の誰もがについて話しませんでしたcall_args_list

これは、正反対の実装を実行できる強力なツールです。MagicMock.assert_called_with()

call_args_listcallオブジェクトのリストです。各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を作成して、ある値で呼び出されたが他の値では呼び出されていないかどうかをテストできます。

于 2016-09-24T16:54:57.103 に答える
1

python stdlib docsによると、python> = 3.5の場合、assert_not_calledを使用する必要があります

my_var.assert_not_called()

注:Python3.5。9は2019年11月1日にリリースされ、この質問は2013年に最初に尋ねられました。

于 2021-11-08T19:04:05.960 に答える