Hi, Trying to get my head around Unit Testing (and Python) and I've come across a strange problem when adding some tests to the example from pyunit-1.4.1\doc\PyUnit.html. class Widget: def __init__(self, widgetname, size=(50,50)): self.name = widgetname self._size = size def func(self): return 4 def name(self): return self.name class WidgetTestCase(unittest.TestCase): def setUp(self): self.widget = Widget("The widget") def testFunc(self): assert self.widget.func() == 3, 'Invalid value' def testName(self): assert self.widget.name() == "The widget", "Invalid name" I'm getting the error "TypeError: 'str' object is not callable" when I run my test suite. It's complaining about the last line of code. However, if I take the function call brackets off (assert self.widget.name == "The widget", "Invalid name") it works fine. I expected it to work like the func() example above it. I did a search on Google for the error string, which turned up a few explanations but none which really helped. Can anyone explain what's happening? Many thanks, Francis. CONFIDENTIALITY NOTICE This communication contains information which is confidential and may also be privileged. It is for the exclusive use of the intended recipient(s). If you are not the intended recipient(s) please note that any distribution, copying or use of this communication or the information in it is strictly prohibited. If you have received this communication in error please notify us by e-mail or by telephone (+44(0) 1322 621100) and then delete the e-mail and any copies of it. This communication is from Shaw & Sons Limited whose registered office is at Shaway House, 21 Bourne Park, Bourne Road, Crayford, Kent DA1 4BZ. The views expressed in this communication may not be the views held by Shaw & Sons Limited. This message has been checked for all known viruses by McAfee VirusScan.
Hi,
Trying to get my head around Unit Testing (and Python) and I've come across a strange problem when adding some tests to the example from pyunit-1.4.1\doc\PyUnit.html.
class Widget: def __init__(self, widgetname, size=(50,50)): self.name = widgetname self._size = size def func(self): return 4 def name(self): return self.name
class WidgetTestCase(unittest.TestCase): def setUp(self): self.widget = Widget("The widget") def testFunc(self): assert self.widget.func() == 3, 'Invalid value' def testName(self): assert self.widget.name() == "The widget", "Invalid name"
I'm getting the error "TypeError: 'str' object is not callable" when I run my test suite. It's complaining about the last line of code. However, if I take the function call brackets off (assert self.widget.name == "The widget", "Invalid name") it works fine. I expected it to work like the func() example above it.
I suspect you may have copied the example incorrectly, but what is happening is this: You have defined a class Widget with a method called 'name', but in your __init__ method you are assigning to an attribute also called 'name'. The attribute is stored in the instance and this hides the method, so when you access self.widget.name you are retrieving the string rather than the method. When you attempt to call the string retrieved by self.widget.name you get an error telling you that you cannot call a string. Remember that functions and methods are first class objects in Python, so for example the test: assert self.widget.func() == 3, 'Invalid value' could equally well be written as: x = self.widget.func assert x() == 3, 'Invalid value' The compiler does not, and indeed cannot, make a distinction between accessing an attribute and calling a method: you could have assigned a function or some other callable to self.widget.name by the time it tries to access it. I hope this help.
CONFIDENTIALITY NOTICE
This communication contains information which is confidential and may also be privileged. It is for the exclusive use of the intended recipient(s). If you are not the intended recipient(s) please note that any distribution, copying or use of this communication or the information in it is strictly prohibited. If you have received this communication in error please notify us by e-mail or by telephone (+44(0) 1322 621100) and then delete the e-mail and any copies of it.
This communication is from Shaw & Sons Limited whose registered office is at Shaway House, 21 Bourne Park, Bourne Road, Crayford, Kent DA1 4BZ. The views expressed in this communication may not be the views held by Shaw & Sons Limited.
This message has been checked for all known viruses by McAfee VirusScan.
Have Shaw & Sons limited considered that appending a confidentiality notice to emails that are patently not intended to be confidential makes it almost impossible for them to defend their position if anyone does distribute an email that really was intended to be confidential? Duncan Booth -- IMPORTANT: This email is intended for the use of the individual addressee(s) named above and may contain information that is confidential, privileged or unsuitable for overly sensitive persons with low self-esteem, no sense of humour or irrational religious beliefs. If you are not the intended recipient, any dissemination, distribution or copying of this email is not authorised (either explicitly or implicitly) and constitutes an irritating social faux pas. Unless the word absquatulation has been used in its correct context somewhere other than in this warning, it does not have any legal or grammatical use and may be ignored. No animals were harmed in the transmission of this email, although the yorkshire terrier next door is living on borrowed time, let me tell you. Those of you with an overwhelming fear of the unknown will be gratified to learn that there is no hidden message revealed by reading this warning backwards, so just ignore that Alert Notice from Microsoft: However, by pouring a complete circle of salt around yourself and your computer you can ensure that no harm befalls you and your pets. If you have received this email in error, please add some nutmeg and egg whites and place it in a warm oven for 40 minutes. Whisk briefly and let it stand for 2 hours before icing.
participants (2)
-
Duncan Booth -
Francis Moore