2017-06-19 3 views
2

Ich schreibe einen Unit-Testfall für eine meiner Python 2.7-Methoden.Python-Einheitstest mock. ValueError: Der Wahrheitswert eines DataFrames ist mehrdeutig

In meiner Testmethode gibt es einen Methodenaufruf, der ein Wörterbuch mit Zeichenfolgenschlüssel und Panadas-Datenframe als Wert für diesen Schlüssel verwendet.

möchte ich eine Interaktionstest für diese Methode schreiben, zu überprüfen, ob sie das Verfahren intern mit der richtigen Wörterbuch ruft

def MethodUnderTest(self): 
    #some code here 
    externalMethod(dictionary_of_string_dataframe) 
    #some code here 

Im Unit-Test, ich meine Assertion schreiben diese Interaktion zu testen, wie diese

mock_externalClass.externalMethod.assert_called_once_with(dictionary_of_string_dataframe) 

ich create dictionary_of_string_dataframe genau so wie es in der tatsächlichen Methode erstellt wird. Tatsächlich habe ich die Hilfsmethode kopiert, die das im Testcode tut, nur um sicherzustellen, dass beide Wörterbücher identisch sind. Ich drucke sogar beide Wörterbücher beim Debuggen der Testmethode auf der Python-Konsole und beide sehen genau gleich aus.

Und ich patch die externe Klasse mit @patch Decorator und alles, was gut funktioniert.

Das Problem ist, dass in der oben erwähnten assert-Anweisung, ich die folgende Fehlermeldung erhalten:

mock_externalClass.externalMethod.assert_called_once_with(dictionary_of_string_dataframe) 
    File "C:\Python27\lib\site-packages\mock\mock.py", line 948, in assert_called_once_with 
    return self.assert_called_with(*args, **kwargs) 
    File "C:\Python27\lib\site-packages\mock\mock.py", line 935, in assert_called_with 
    if expected != actual: 
    File "C:\Python27\lib\site-packages\mock\mock.py", line 2200, in __ne__ 
    return not self.__eq__(other) 
    File "C:\Python27\lib\site-packages\mock\mock.py", line 2196, in __eq__ 
    return (other_args, other_kwargs) == (self_args, self_kwargs) 
    File "C:\Python27\lib\site-packages\pandas\core\generic.py", line 953, in __nonzero__ 
    .format(self.__class__.__name__)) 
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Ich habe Suche auf dem Valueerror aber nicht viel Hilfe. Kann mir jemand sagen, was hier vor sich geht?

habe ich die folgende Frage prüfen, aber das ist nicht

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()

+0

Also nur um zu verdeutlichen: Sie haben zwei Wörterbücher, die Strings zu Pandas Datenrahmen zuordnen, und Sie möchten überprüfen, ob sie gleich sind. Sie schreiben den Komponententest selbst, und selbst bei zwei Wörterbüchern, die mit denselben Funktionen und Parametern erstellt wurden, erhalten Sie den obigen Fehler. – victor

+0

Wenn ich den Testfall runt, trifft es eine externe Methode innerhalb der zu testenden Methode mit einem dict von string: dataframe. Im Testfall selbst teste ich diese Interaktion anhand der in meiner Frage angegebenen Aussage und erstelle den dict-Wert in der Testmethode für mock_externalClass.externalMethod.assert_called_once_ mit der gleichen Hilfsmethode, die in der zu testenden Methode verwendet wird. Ich erhalte jedoch einen Fehler. – Hary

+0

IMHO du nimmst den falschen Ansatz. Sie versuchen im Grunde, Ihren Code zu zwingen, den Test zu bestehen, anstatt den Test die gewünschten Ergebnisse durchzusetzen. Wenn die Signatur der externen Methode geändert wird, erkennt Ihr Test die Änderung des Codes nicht, aber wenn Sie den Code nur korrigieren, wird Ihr Test fehlschlagen.Ich schlage vor, dass Sie den Code, der die Eingabe ableitet, entkoppeln und die externe Methode in seine eigene Methode aufrufen und diese Methode isoliert testen, um Ihre Bedenken zu trennen. – Dan

Antwort

3

Dies geschieht, half da unittest.mock zwischen Eingangswerten mit == oder != vergleicht. Pandas-Datenframes können jedoch nicht auf ähnliche Weise verglichen werden. Stattdessen müssen Sie die Methode .equals von DataFrames verwenden.

https://github.com/testing-cabal/mock/blob/master/mock/mock.py

Eine mögliche Lösung ist, Ihren eigenen Unit-Test, dass iteriert durch das Wörterbuch zu schreiben und mit dem .equals Verfahren zwischen Datenrahmen vergleicht.

Eine andere ist die __equals__ Methode der Pandas Datenrahmen zu überschreiben, so wenn mock vergleicht zwischen ihnen wird es die richtige Methode verwenden.

Verwandte Themen