J'ai rencontré quelque chose de mystérieux, lors de l'utilisation du patch décorateur du package simulé intégré avec le montage pytest.
J'ai deux modules
-----test folder
-------func.py
-------test_test.py
dans func.py:
def a():
return 1
def b():
return a()
dans 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()
Il semble que le patch décorer ne soit pas compatible avec le luminaire pytest. Quelqu'un a-t-il une idée de cela? Tnanks
J'ai eu le même problème et la solution pour moi était d'utiliser la bibliothèque fictive dans la version 1.0.1 (avant d'utiliser unittest.mock dans la version 2.6.0). Maintenant ça marche comme un charme :)
Lors de l'utilisation de pytest fixture
avec mock.patch
, l'ordre des paramètres de test est crucial.
Si vous placez un paramètre de luminaire avant un paramètre simulé:
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(my_fixture, mocked_class):
alors l'objet factice sera dans my_fixture
et mocked_class
sera recherché comme appareil:
fixture 'mocked_class' not found
Mais, si vous inversez l'ordre, placez le paramètre fixture à la fin:
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(mocked_class, my_fixture):
alors tout ira bien.
Depuis Python3., le module mock
a été tiré dans le unittest
bibliothèque. Il existe également un backport (pour les versions précédentes de Python) disponible en tant que bibliothèque autonome mock
.
La combinaison de ces 2 bibliothèques au sein de la même suite de tests génère l'erreur mentionnée ci-dessus:
E fixture 'fixture_name' not found
Dans l'environnement virtuel de votre suite de tests, exécutez pip uninstall mock
, et assurez-vous que vous n'utilisez pas la bibliothèque rétroportée aux côtés de la bibliothèque principale non unifiée. Lorsque vous réexécutez vos tests après la désinstallation, vous verrez ImportError
s si tel était le cas.
Remplacez toutes les instances de cette importation par from unittest.mock import <stuff>
.
Cela ne répond pas directement à votre question, mais il existe le plugin pytest-mock qui vous permet d'écrire ceci à la place:
def test_compute_scores(brands, mock):
mock_b = mock.patch('test_test.b')
a()
Espérons que cette réponse à une vieille question aidera quelqu'un.
Tout d'abord, la question n'inclut pas l'erreur, donc nous ne vraiment savons pas ce qui se passe. Mais je vais essayer de fournir quelque chose qui m'a aidé.
Si vous voulez un test décoré avec un objet patché, alors pour qu'il fonctionne avec pytest, vous pouvez simplement faire ceci:
@mock.patch('mocked.module')
def test_me(*args):
mocked_module = args[0]
Ou pour plusieurs patchs:
@mock.patch('mocked.module1')
@mock.patch('mocked.module')
def test_me(*args):
mocked_module1, mocked_module2 = args
pytest recherche les noms des appareils à rechercher dans la fonction/méthode de test. Fournir le *args
L'argument nous donne une bonne solution de contournement pendant la phase de recherche. Donc, pour inclure un appareil avec des correctifs, vous pouvez le faire:
# from question
@pytest.fixture(scope="module")
def brands():
return 1
@mock.patch('mocked.module1')
def test_me(brands, *args):
mocked_module1 = args[0]
Cela a fonctionné pour moi en exécutant python 3.6 et pytest 3.0.6.