J'ai la classe simplifiée suivante dont je me moque:
class myClass(object):
@staticmethod
def A():
#...
def check(self):
#code...
value = self.A()
#more code...
Dans mon premier test, je me moque uniquement de la méthode A
from Django.test import TestCase
from mock import MagicMock
import myClass
class FirstTest(TestCase):
def setUp(self):
myClass.A = MagicMock(return_value = 'CPU')
def test(self):
#some tests
myClassObj = myClass()
myClassObj.check()
Alors que dans mon deuxième test, je me moque de toute la méthode de vérification:
from Django.test import TestCase
from mock import MagicMock
import myClass
class SecondTest(TestCase):
def setUp(self):
myClass.check = MagicMock(return_value = someObject)
def test(self):
#some tests
myClassObj = myClass()
myClassObj.check()
Maintenant, mes assertions de mon premier test échouent parce qu'au lieu d'appeler check()
et de se moquer de A()
à l'intérieur de check()
, il appelle la check()
complètement moquée de mon deuxième test.
Existe-t-il un moyen d'effacer et de définir la méthode comme "normale" après le test? J'ai déjà essayé myClass.check.reset_mock()
, mais il ne semble rien faire. Déplacer l'ordre de mes tests ne fait rien non plus.
J'utilise mock 1.0b1 pour python de http://pypi.python.org/pypi/mock/
Vous pouvez ranger la fonction sur vous-même et la remettre lorsque vous avez terminé.
import unittest
from mock import MagicMock
from MyClass import MyClass
class FirstTest(unittest.TestCase):
def setUp(self):
self.A = MyClass.A
MyClass.A = MagicMock(name='mocked A', return_value='CPU')
def tearDown(self):
MyClass.A = self.A
def test_mocked_static_method(self):
print 'First Test'
print MyClass.check
print MyClass.A
class SecondTest(unittest.TestCase):
def setUp(self):
MyClass.check = MagicMock(name='mocked check', return_value=object)
def test_check_mocked_check_method(self):
print 'Second Test'
print MyClass.check
print MyClass.A
if __name__ == '__main__':
unittest.main()
L'exécution de ce fichier donne la sortie suivante:
First Test
<unbound method MyClass.check>
<MagicMock name='mocked A' id='141382732'>
Second Test
<MagicMock name='mocked check' id='141382860'>
<unbound method MyClass.A>
Je me suis retrouvé à utiliser le patch décorateur beaucoup plus que setUp et tearDown maintenant. Dans ce cas, vous pourriez faire
from mock import patch
@patch('MyClass.A')
def test_mocked_static_method(self, mocked_A)
mocked_A.return_value = 'CPU'
# This mock will expire when the test method is finished
Vous pouvez utiliser mock.patch
en tant que décorateur ou gestionnaire de contexte:
from mock import patch, MagicMock
@patch('myClass.A', MagicMock(return_value='CPU'))
def test(self):
pass
ou:
def test(self):
with patch('myClass.A', MagicMock(return_value='CPU')):
pass
Si vous ne fournissez pas d'objet fantaisie à patch
, il fournira une maquette auto-spécifiée que vous pouvez modifier:
@patch('myClass.A')
def test(self, mock_A):
mock_A.return_value = 'CPU'
pass
ou:
def test(self):
with patch('myClass.A') as mock_A:
mock_A.return_value = 'CPU'
pass
Dans tous les cas, la valeur d'origine sera restaurée lorsque la fonction de test décorée ou le gestionnaire de contexte se terminera.