Connecting Tech Pros Worldwide Forums | Help | Site Map

Unittest - testing properties (read-only attributes)

Paul Moore
Guest
 
Posts: n/a
#1: Jul 18 '05
I have a class with a read-only attribute, and I want to add a unit
test to ensure that it really *is* read-only. I can do this as

def test_readonly(self):
"""Value and multiplier must be readonly"""
try:
self.combat.value = 1
self.fail("Value is not read only")
except AttributeError:
pass

That works, but it seems a bit clumsy. Is there a better way?

Thanks,
Paul.
--
XML with elementtree is what makes me never have think about XML
again. -- Istvan Albert

Diez B. Roggisch
Guest
 
Posts: n/a
#2: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Paul Moore wrote:
[color=blue]
> I have a class with a read-only attribute, and I want to add a unit
> test to ensure that it really *is* read-only. I can do this as
>
> def test_readonly(self):
> """Value and multiplier must be readonly"""
> try:
> self.combat.value = 1
> self.fail("Value is not read only")
> except AttributeError:
> pass
>
> That works, but it seems a bit clumsy. Is there a better way?[/color]


By using setattr, you could refactor the above code into a function. Looks
like this (untested):

def test_readonly(self, instance, attribute, value=1):
"""Value and multiplier must be readonly"""
try:
setattr(instance, attribute, value)
self.fail("Value is not read only")
except AttributeError:
pass


Then the testing becomes one line:

self.test_readonly(self.combat, "value")


--
Regards,

Diez B. Roggisch
Roy Smith
Guest
 
Posts: n/a
#3: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


In article <uu0o5c0br.fsf@yahoo.co.uk>, Paul Moore <pf_moore@yahoo.co.uk>
wrote:
[color=blue]
> I have a class with a read-only attribute, and I want to add a unit
> test to ensure that it really *is* read-only. I can do this as
>
> def test_readonly(self):
> """Value and multiplier must be readonly"""
> try:
> self.combat.value = 1
> self.fail("Value is not read only")
> except AttributeError:
> pass
>
> That works, but it seems a bit clumsy. Is there a better way?
>
> Thanks,
> Paul.[/color]

You want something like

self.assertRaises(AttributeError, lambda: self.combat.value = 1)
Peter Hansen
Guest
 
Posts: n/a
#4: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Roy Smith wrote:[color=blue]
> You want something like
>
> self.assertRaises(AttributeError, lambda: self.combat.value = 1)[/color]

Or, combining the two responses and avoiding the lambda:

self.assertRaises(AttributeError, setattr, self.combat, 'value', 1)

Hmm... this might be a case where the lambda form is actually the
more readable one...

-Peter
Paul Rubin
Guest
 
Posts: n/a
#5: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Peter Hansen <peter@engcorp.com> writes:[color=blue][color=green]
> > You want something like
> > self.assertRaises(AttributeError, lambda: self.combat.value = 1)[/color]
>
> Or, combining the two responses and avoiding the lambda:
>
> self.assertRaises(AttributeError, setattr, self.combat, 'value', 1)
>
> Hmm... this might be a case where the lambda form is actually the
> more readable one...[/color]

Yes, assignment expressions could make code more readable, if Python
supported them.
Paul Moore
Guest
 
Posts: n/a
#6: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Peter Hansen <peter@engcorp.com> writes:
[color=blue]
> Roy Smith wrote:[color=green]
>> You want something like
>> self.assertRaises(AttributeError, lambda: self.combat.value = 1)[/color]
>
> Or, combining the two responses and avoiding the lambda:
>
> self.assertRaises(AttributeError, setattr, self.combat, 'value', 1)
>
> Hmm... this might be a case where the lambda form is actually the
> more readable one...[/color]

Thanks, I hadn't thought of setattr. I was bitten by the "assignment
is a statement, so can't be used in a lambda" issue, as well :-)

Paul.
--
It was a machine, and as such only understood one thing. Being clobbered
with big hammers was something it could relate to. -- Tom Holt
Duncan Booth
Guest
 
Posts: n/a
#7: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Paul Rubin wrote:
[color=blue]
> Peter Hansen <peter@engcorp.com> writes:[color=green][color=darkred]
>> > You want something like
>> > self.assertRaises(AttributeError, lambda: self.combat.value = 1)[/color]
>>
>> Or, combining the two responses and avoiding the lambda:
>>
>> self.assertRaises(AttributeError, setattr, self.combat, 'value', 1)
>>
>> Hmm... this might be a case where the lambda form is actually the
>> more readable one...[/color]
>
> Yes, assignment expressions could make code more readable, if Python
> supported them.
>[/color]

An assignment expression, if such a thing existed wouldn't help here.

The point being that the expression must be evaluated inside the exception
handler in assertRaises, so you either need to delay the evaluation with a
lambda, or by passing the function and arguments in separately. If you had
an assignment expression it would be roughly equivalent to:

self.assertRaises(AttributeError, setattr(self.combat, 'value', 1))

which will throw the AttributeError instead of passing the test.

Duncan Booth
Guest
 
Posts: n/a
#8: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Duncan Booth wrote:
[color=blue]
> An assignment expression, if such a thing existed wouldn't help here.[/color]

Although of course it would help if still inside a lambda.
Paul Rubin
Guest
 
Posts: n/a
#9: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Duncan Booth <duncan.booth@invalid.invalid> writes:[color=blue]
> An assignment expression, if such a thing existed wouldn't help here.
>
> The point being that the expression must be evaluated inside the exception
> handler in assertRaises, so you either need to delay the evaluation with a
> lambda, or by passing the function and arguments in separately. If you had
> an assignment expression it would be roughly equivalent to:
>
> self.assertRaises(AttributeError, setattr(self.combat, 'value', 1))
>
> which will throw the AttributeError instead of passing the test.[/color]

Yes. The example I quoted used an assignment expression inside a
lambda. The person who posted it, and the person who followed it up
with the setattr alternative, both didn't notice that the assignment
expression wasn't valid Python. However, my post came out sounding
grumpier than I intended ;).
Roy Smith
Guest
 
Posts: n/a
#10: Jul 18 '05

re: Unittest - testing properties (read-only attributes)


Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote:[color=blue]
> The example I quoted used an assignment expression inside a
> lambda. The person who posted it,[/color]

That was me.
[color=blue]
> and the person who followed it up
> with the setattr alternative, both didn't notice that the assignment
> expression wasn't valid Python.[/color]

Ugh. No, I hadn't noticed it. Thanks for pointing it out.

I don't use lambdas much. In fact, the only time I ever do use them is for
an assertRaises unit test. I've always thought that "assignment is a
statement not an expression" was one of Python's warts, and this is just
another example of why it is. Of course, "lambda isn't just a def body" is
a wart too :-)
[color=blue]
> However, my post came out sounding
> grumpier than I intended ;).[/color]

Actually, I hadn't noticed that either. :-)
Closed Thread