28

Pythonテストファイルに次のようなものがあります:

from mock import patch,
from ..monkey import ook
[...]
@patch('monkey.ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(ook())
    mock_ook.run.assert_called_once_with('')

このテストを実行すると、ImportError: No module named monkey. 明らかに、私がパッチを当てているパスは正しくありません。sys.pathただし、またはをいじらずに正しくする方法がわかりませんPYTHONPATH

ポインタはありますか?

4

7 に答える 7

25

私はこれに出くわすまで、Dan Passaroのソリューションを使用しpatch.objectました – これは私にはさらに良く見えます:

from unittest.mock import patch,
from .. import monkey
[...]
@patch.object(monkey, 'ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(monkey.ook())
    mock_ook.run.assert_called_once_with('')

利点:

  • 定型コードは必要ありません__name__ + '.object_to_be_mocked'
  • テスト ケースのすべての依存関係は、ファイルの先頭にimportステートメントとして明確に記述されています。
  • モック アウトしようとしているオブジェクトのドット ネームがより長く (「amazon.jungle.monkey.ook」など)、したがって を記述する@patch.object(amazon.jungle.monkey, 'ook', …)場合、IDE の静的コード分析により、少なくともamazon.jungle.monkeyが有効な変数であることを確認できます。すべてを文字列として記述しなかったためです'amazon.jungle.monkey.ook'

短所:

  • することはできませんが、実行してアクセスするfrom ..monkey import ook必要があります。これを頻繁に記述する必要がある場合は、便宜上、テストの最初に追加します。(または、 のこの特定のプロパティをモックする必要がない場合に備えて、 import ステートメントにも。)from .. import monkeyookmonkeymonkey.ookook = monkey.ookmonkey
于 2014-05-24T11:48:19.247 に答える
6

受け入れられた答えに基づいて、これが望ましい目標を達成するための最もクリーンな方法であると私は信じています:

from mock import patch
from .. import monkey

@patch(monkey.__name__+'.ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(monkey.ook())
    mock_ook.run.assert_called_once_with('')
于 2015-11-30T10:54:46.900 に答える
1

from ..monkey import ookモジュールから実行すると、pkg1.pgk2.mymodule最終的にはpkg1.pgk2.mymodule.ook.

これはook、実行したモジュールの名前空間にありますfrom ... import ...。そして、それがパッチを適用する必要があるターゲットです。

したがって、パッチを適用するだけですpkg1.pkg2.mymodule.ook

from unittest.mock import patch # mypackage.mymodule.patch
from ..monkey import ook        # mypacket.mymodule.ook

with patch("pkg1.pgk2.mymodule.ook"):
   ....

他の人が指摘したように、インポートを行ったのと同じモジュールからパッチを適用する場合は__name__、ドット付きパッケージ名を取得するために使用できますが、別のモジュールからパッチを適用する場合は、それを綴る必要があります。

インポートするものは何でも target からパッチ可能であることを覚えておいてくださいmodulethatimports.nameimported

于 2015-09-24T13:12:30.790 に答える
0

monkeyこれは、インポートするのではなく、インポートするという事実から来ていると思いますook。からサルをインポートする..と、動作するはずです。それ以外の場合は、パッチを呼び出しますook

于 2013-01-15T17:15:10.537 に答える
-1

インポートには完全なパスを使用してください。たとえば、次のファイルシステムがある場合:

  • 根/
    • ダミー/
      • ふー/
        • モジュール.py
    • ダミー2/
      • module2.py

以下を使用して、module2.py から module.py をインポートできます。

from root.dummy.foo import module
于 2013-01-15T16:20:03.263 に答える