web-dev-qa-db-ja.com

@Patchデコレータはpytestフィクスチャと互換性がありません

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フィクスチャと互換性がないようです。誰か洞察力がありますか?タンクス

31
Hello lad

同じ問題があり、解決策は1.0.1バージョンでモックライブラリを使用することでした(2.6.0バージョンでunittest.mockを使用する前)。今それは魅​​力のように機能します:)

2
Konrad Kocik

Pytest fixturemock.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):

その後、すべてがうまくいきます。

23
bux

Python3.以降、mockモジュールがunittestにプルされました図書館。スタンドアロンライブラリmockとして利用できるバックポート(以前のバージョンのPython用)もあります。

同じテストスイート内でこれら2つのライブラリを組み合わせると、上記のエラーが発生します。

E       fixture 'fixture_name' not found

テストスイートの仮想環境内でpip uninstall mockを実行し、コアユニットテストライブラリと一緒にバックポートされたライブラリを使用していないことを確認します。アンインストール後にテストを再実行すると、これが当てはまる場合はImportErrorsが表示されます。

このインポートのすべてのインスタンスをfrom unittest.mock import <stuff>で置き換えます。

5
The Aelfinn

これはあなたの質問に直接対処しませんが、代わりにこれを書くことを可能にする pytest-mock プラグインがあります:

def test_compute_scores(brands, mock):                 
     mock_b = mock.patch('test_test.b')
     a()
3
Bruno Oliveira

うまくいけば、古い質問に対するこの答えが誰かを助けるでしょう。

まず、質問にはエラーが含まれていないため、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を実行している私にとってはうまくいきました。

2
404