Avoid converting functions to methods in a class

Jean-Michel Pichavant jeanmichel at sequans.com
Tue Feb 23 07:50:15 EST 2010


Steven D'Aprano wrote:
> I have a convention when writing unit tests to put the target of the test 
> into a class attribute, as follows:
>
> class MyTest(unittest.TestCase):
>     target = mymodule.someclass
>
>     def test_spam(self):
>         """Test that someclass has a spam attribute."""
>         self.failUnless(hasattr(self.target, 'spam'))
>
>
> It works well until I write a test for stand-alone functions:
>
> class AnotherTest(unittest.TestCase):
>     target = mymodule.function
>
>     def test_foo(self):
>         self.assertEquals(self.target('a', 'b'), 'foo')
>
> The problem is that target is turned into a method of my test class, not 
> a standalone function, and I get errors like:
>
> TypeError: function() takes exactly 2 arguments (3 given)
>
> The solution I currently use is to drop the target attribute in this 
> class, and just refer to mymodule.function in each individual test. I 
> don't like this solution because it violates Once And Only Once: if the 
> function changes name, I have to make many edits to the test suite rather 
> than just one.
>
> Are there any better solutions?
>
>
>   

It looks like it works when declaring foo as static:

import unittest

def foo(a,b):
    return 'fooo'

class AnotherTest(unittest.TestCase):
    target = staticmethod(foo)

    def test_foo(self):
        self.assertEquals(self.target('a', 'b'), 'foo')
   
    def runTest(self):
        self.test_foo()

AnotherTest().runTest()
...AssertionError: 'fooo' != 'foo'

JM



More information about the Python-list mailing list