10

Einer meiner Attribute ist eine Eigenschaft, wo die Setter eine Validierungsfunktion aufruft, die eine Ausnahme auslöst, wenn der neue Wert ist ungültig:Testing Ausfall einer Zuweisung mit Unittest

pos.offset = 0 
# @offset.setter calls validate(offset=0) 
# PositionError: Offset may not be 0. 

Ich versuche, einen Test hinzufügen um sicherzustellen, dass dies fehlschlägt. Ich kann jedoch nicht herausfinden, wie man Assets dazu bringen kann, mit einer Aufgabe zu arbeiten.

Die normale Syntax von assertRaises erfordert eine Methode, kein Attribut/Eigenschaft:

self.assertRaises(PositionError, pos.offset, 0) 
# TypeError: 'int' object is not callable 

Die anderen Formen habe ich versucht, sind ungültig Python:

self.assertRaises(PositionError, pos.offset = 0) 
# SyntaxError: Keyword can't be an expression 
self.assertRaises(PositionError, lambda: pos.offset = 0) 
# SyntaxError: lambda cannot contain assignment 

Wie kann ich Ausfall testen der Zuordnung zu einer Immobilie?

Hinweis: Python 2.6, weiß ich Unittest in 2,7

Antwort

14

Wenn Sie unittest verwenden möchten, um zu testen, dass eine Ausnahme in einem Block von Code auftritt und nicht nur ein Funktionsaufruf, können Sie assertRaises als Kontext-Manager verwenden:

with self.assertRaises(PositionError): 
    pos.offset = 0 

Diese Verwendung finden Sie in die unittest docs.

Obwohl dies in Python 2.6 nicht verfügbar ist und nicht für Sie funktionieren wird (ich habe gerade Ihre Notiz gesehen), denke ich, dass es sich lohnt, unter die Antworten aufzunehmen, da dies wahrscheinlich der klarere Weg ist, dies für Python zu tun 2.7+.

+0

Ja, ich stimme zu, das ist klarer für 2.7+ – Lenna

7

Bevor Python einige neue Features hat 2.7, Sie setattr(object, name, value)(doc) verwenden möchten. Dadurch können Sie einen Wert für ein Attribut festlegen.

self.assertRaises(PositionError, setattr, pos, "offset", 0) 
# ... ok 

Dies sollte immer funktionieren, denn wenn das Attribut eine Eigenschaft ist und damit „im Geheimen“ eine Funktion aufruft, muss es innerhalb einer Klasse sein. Ich glaube nicht, dass eine Standardzuweisung fehlschlagen kann (obwohl ein Ausdruck auf der rechten Seite fehlschlagen kann, d. H. x = 1/0).

+0

Die Zuweisung kann aus verschiedenen Gründen fehlschlagen (z. B. Hinzufügen eines Attributs, das nicht in "__slots__" enthalten ist), auch wenn Sie keinen Deskriptor haben, aber dies ist ansonsten die richtige Antwort. – Julian

+0

@Julian: Ah, guter Punkt. Ich bin nicht vertraut mit '__slots__'. – Lenna