Jednym z moich atrybutów jest właściwość, w której seter wywołuje funkcję walidacji, która podnosi wyjątek, jeśli nowa wartość jest nieprawidłowa:

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

Próbuję dodać test, aby zapewnić, że nie powiedzie się. Nie mogę jednak dowiedzieć się, jak uzyskać assertraises do pracy z zadaniem.

Normalna składnia assertraisów wymaga metody, a nie atrybutu / nieruchomości:

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

Inne formy, które wypróbowałem, są nieprawidłowe 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

Jak przetestować awarię przypisania do nieruchomości?

Uwaga: Python 2.6, wiem, że niektóre nowe funkcje w 2.7

13
Lenna 17 sierpień 2012, 20:27

2 odpowiedzi

Najlepsza odpowiedź

Gdy chcesz użyć unittest, aby przetestować, że wyjątek występuje w bloku kodu, a nie tylko włączenie funkcji, możesz użyć assertRaises jako menedżera kontekstu:

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

To użycie można znaleźć w Unitest Docs.

Chociaż jest to niedostępne w Pythonie 2.6 i nie będzie działać dla Ciebie jako takiego (właśnie widziałem twoją notatkę), myślę, że warto włączyć do odpowiedzi, ponieważ jest to prawdopodobnie wyraźniejszy sposób na to dla Pythona 2.7+.

17
Wilduck 17 sierpień 2012, 16:56

Przed Python 2.7, chcesz użyć setattr(object, name, value) ( doc ) ). Pozwala to ustawić wartość do atrybutu.

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

Powinno to zawsze działać, ponieważ jeśli atrybut jest właściwością, a zatem "potajemnie" wzywa funkcję, musi być w klasie. Nie sądzę, aby standardowe przypisanie może się niepowodzenie (chociaż wyrażenie po prawej stronie może zawieść, tj. x = 1/0).

8
Lenna 15 styczeń 2013, 17:25