2012-04-12 9 views
5

Ich habe eine Testsuite (mit Nase, nicht Unittest), und ich möchte eine Funktion patchen, um eine bestimmte Sequenz von Werten für jeden Test in der Testklasse zurückzugeben. Mein erster Versuch, ein vereinfachtes Beispiel verwendet wird, war:Patchen einer Funktion mit Mock

@patch('time.clock', MagicMock(side_effects=[1, 2])) 
class Tests: 
    def test_1(self): 
     assert time.clock() == 1 
     assert time.clock() == 2 

    def test_2(self): 
     assert time.clock() == 1 
     assert time.clock() == 2 

jedoch die MagicMock Instanz nur einmal erstellt wird, so dass der zweite Test schlägt fehl, wenn die Nebenwirkungen ausgehen. Ich kann jede Testmethode separat patchen, aber ich möchte den Patch-Decorator nicht wirklich über alle kopieren (es gibt viel mehr Tests als in diesem Beispiel!) Die andere Möglichkeit wäre, den Patch zu erstellen die Setup-Code wie folgt aus:

class Tests: 
    def setup(self): 
     self.old_clock = time.clock 
     time.clock = MagicMock(side_effects=[1, 2]) 

    def teardown(self): 
     time.clock = self.old_clock 

    def test_1(self): 
     assert time.clock() == 1 
     assert time.clock() == 2 

    def test_2(self): 
     assert time.clock() == 1 
     assert time.clock() == 2 

Aber sparen und die ursprüngliche Funktion Definition Wiederherstellung scheint wie etwas, das Mock sollte automatisch tun können. Gibt es eine andere Methode, dies zu tun, die ich vermisse? Oder ist mein letztes Beispiel der beste Weg, dies zu tun?

Antwort

2
a = (x for x in [1,2]) 

x = lambda : next(a) 

x() 

Out: 1

x() 

Out: 2

Setzen Sie Ihre Antworten in eine Liste. Ändern Sie X für Ihren gewünschten Namen.

+0

Ich habe keine Ahnung, was Sie auf hier zu bekommen. Es scheint die Frage überhaupt nicht zu verbinden und sieht wie eine komplizierte Schreibweise aus: x = [1, 2] .__ iter __(). Next'. Was versuchst du zu sagen? – aquavitae

+0

gut. Sie möchten einen Weg finden, um eine Funktion nachzuahmen. Sie jetzt die Reihenfolge der Antworten. Nein? x = ["Ihre erste Antwort", "Ihre zweite Antwort", "... etc"] .__ iter __(). Nächste Löst das Problem. – Nasgar

+0

Ich weiß, wie man einen Iterator erstellt und eine Funktion vortäuscht. Meine Frage war, ob es eine einfache Möglichkeit gibt, den Mock für jede Testfunktion zurückzusetzen. – aquavitae

1

sollten Sie gelten nur den Patch auf jeden Test, statt es auf die Klasse Anwendung:

class Tests: 
    @patch('time.clock', MagicMock(side_effects=[1, 2])) 
    def test_1(self): 
     assert time.clock() == 1 
     assert time.clock() == 2 

    @patch('time.clock', MagicMock(side_effects=[1, 2])) 
    def test_2(self): 
     assert time.clock() == 1 
     assert time.clock() == 2