Pytestフィクスチャと統合されたモックパッケージのパッチデコレータを使用しているときに、不思議なことに遭遇しました。
2つのモジュールがあります
-----test folder
-------func.py
-------test_test.py
func.py:
def a():
return 1
def b():
return a()
test_test.py
import pytest
from func import a,b
from mock import patch,Mock
@pytest.fixture(scope="module")
def brands():
return 1
mock_b=Mock()
@patch('test_test.b',mock_b)
def test_compute_scores(brands):
a()
パッチ装飾はpytestフィクスチャと互換性がないようです。誰か洞察力がありますか?タンクス
同じ問題があり、解決策は1.0.1バージョンでモックライブラリを使用することでした(2.6.0バージョンでunittest.mockを使用する前)。今それは魅力のように機能します:)
Pytest fixture
をmock.patch
とともに使用する場合、テストパラメータの順序が重要です。
モックされたパラメータの前にフィクスチャパラメータを配置する場合:
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(my_fixture, mocked_class):
次に、モックオブジェクトはmy_fixture
にあり、mocked_class
はフィクスチャとして検索されます。
fixture 'mocked_class' not found
ただし、順序を逆にする場合は、フィクスチャパラメータを最後に配置します。
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(mocked_class, my_fixture):
その後、すべてがうまくいきます。
Python3.以降、mock
モジュールがunittest
にプルされました図書館。スタンドアロンライブラリmock
として利用できるバックポート(以前のバージョンのPython用)もあります。
同じテストスイート内でこれら2つのライブラリを組み合わせると、上記のエラーが発生します。
E fixture 'fixture_name' not found
テストスイートの仮想環境内でpip uninstall mock
を実行し、コアユニットテストライブラリと一緒にバックポートされたライブラリを使用していないことを確認します。アンインストール後にテストを再実行すると、これが当てはまる場合はImportError
sが表示されます。
このインポートのすべてのインスタンスをfrom unittest.mock import <stuff>
で置き換えます。
これはあなたの質問に直接対処しませんが、代わりにこれを書くことを可能にする pytest-mock プラグインがあります:
def test_compute_scores(brands, mock):
mock_b = mock.patch('test_test.b')
a()
うまくいけば、古い質問に対するこの答えが誰かを助けるでしょう。
まず、質問にはエラーが含まれていないため、reallyは何が起こっているのかを知りません。しかし、私は私に役立つ何かを提供しようとします。
パッチが適用されたオブジェクトで装飾されたテストが必要な場合、それをpytestで機能させるには、次のようにします。
@mock.patch('mocked.module')
def test_me(*args):
mocked_module = args[0]
または、複数のパッチの場合:
@mock.patch('mocked.module1')
@mock.patch('mocked.module')
def test_me(*args):
mocked_module1, mocked_module2 = args
pytestは、テスト関数/メソッドで検索するフィクスチャの名前を探しています。 *args
引数は、検索フェーズの適切な回避策を提供します。したがって、パッチでフィクスチャを含めるには、次のようにします。
# from question
@pytest.fixture(scope="module")
def brands():
return 1
@mock.patch('mocked.module1')
def test_me(brands, *args):
mocked_module1 = args[0]
これは、python 3.6およびpytest 3.0.6を実行している私にとってはうまくいきました。