私はPythonおよびPythonでのユニットテストに比較的慣れていません。Javaの世界から、モックの概念を知っていますが、何とはかなり異なるようですPythonで見ることができます。
私はこのガイドを見つけましたが、とても役に立ちました: http://www.voidspace.org.uk/python/mock/index.html
しかし、依存関係をモックアウトした私の(もう少し複雑な)テストを書いたとき、私はストレージの動作に気づきました。私は、期待どおりに機能しない、縮小された単純な例を作成することにしました。
これを見て、結果と私がコメントとして追加した私の期待:
_import unittest
from mock import patch, Mock, MagicMock
class BasicTest(unittest.TestCase):
@patch("StringIO.StringIO")
def testSomethingNotWorkingAsExpected(self, StringIOMock):
StringIOMock.assert_called_once() # asserts, but why?
@patch("StringIO.StringIO")
def testSomethingSomehowWorking(self, StringIOMock):
# self.instantiateStringIO() # intentionally commented out
assert StringIOMock.called # does not assert (leading to failure of this test); as expected. If the above line is not commented, this asserts as expected.
def instantiateStringIO(self):
import StringIO
StringIO.StringIO()
_
assert_called_once()
がまだインスタンス化されていないのに、StringIO
のインスタンス化をアサートするのはなぜですか?そして、なぜ_assert ClassMock.called
_が期待される結果をもたらすのですか?
_assert not ...
_を使用してメソッドをアサートすることが呼び出されていない: 関数/メソッドがMock を使用して呼び出されていない私の場合、not
を省略してこのパターンを反転させました。
どこかで、インスタンスを参照するパターン_ClassMock.return_value
_を見つけました。しかし、これは、モックのインスタンスが呼び出される前に操作する方法として理解しているのであり、基になるコードが内部で作成した可能性のあるインスタンスにアクセスする方法としては理解していません。それとも私は間違っていますか?
私の環境:
おそらく、モック/パッチについての私の理解は間違っています。クラスのモックの機能とその仕組みを誰かが追加で説明してくれませんか?
... testSomethingSomehowWorking
でコメントするために括弧で言い換えを追加
これは出力です:
_.F
======================================================================
FAIL: testSomethingSomehowWorking (test_test.BasicTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/mock.py", line 1224, in patched
return func(*args, **keywargs)
File "test_test.py", line 15, in testSomethingSomehowWorking
assert StringIOMock.called # does not assert; as expected
AssertionError
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
_
メソッド_assert_called_once
_は存在せず、アサーションを実行しません。 StringIOMock.assert_foo_bar_does_not_exist()
やその他のメソッドを書くことと何の違いもありません。モックライブラリは、モックで呼び出されたメソッドが実際に存在するかどうかをチェックしません。
_assert_called_once_with
_ を使用すると、期待どおりに失敗します。
spec
パラメータを使用して、存在しないメソッドを呼び出すときにエラーを発生させることができます。
_@patch("StringIO.StringIO", spec=StringIO.StringIO)
def testSomethingNotWorkingAsExpected(self, StringIOMock):
StringIOMock.assert_called_once() # will fail as the method doesn't exist
_