Testing within a python class method
<p>I am using unittest in python to test a project.  The project defines classes that are intended for other python developers to subclass. The project can then be run and utilizes the subclasses that the user has written.</p>

<p>I want to test that the subclass's methods are being passed correct data by the project. How can I do this?  It is not straightforward to call <code>unittest.TestCase.assert*</code> methods from within the test classes which are subclassing from the project.</p>

<p>I have tried setting the <code>TestCase</code> object to a global variable and calling the <code>TestCase</code> object's assert methods from within the subclass methods, but the global variable does not seem to be defined from within the scope of the test class methods.</p>

<p>Example</p>

<pre><code>import unittest
import myproject


class TestProjectClass(unittest.TestCase):
    def test_within_class_method(self):
        myproject.run(config_file_pointing_to_ProjectClass)     # Calls SomeUsersClass.project_method()


class SomeUsersClass(myproject.UserClassTemplate):
    def project_method(self, data_passed_by_project):
        #want to test data_passed_by_project in here
        pass
</code></pre>

<p>I was able to get this working by using <code>raise</code> to pass a custom exception up to the <code>unittest.TestCase</code>.  The custom exception can be packed with whatever data needs to be tested.  I don't show it here, but <code>test_helper.py</code> is just a bare bones subclass of <code>Exception</code>.</p>

<pre><code>import unittest
import myproject
from test_helper import PassItUpForTesting


class TestProjectClass(unittest.TestCase):
    def test_within_class_method(self):
        try:
            # The following line calls SomeUsersClass.project_method()
            myproject.run(config_file_pointing_to_ProjectClass)
        except PassItUpForTesting as e:
            # Test things using e.args[0] here
            # Example test
            self.assertEqual(e.args[0].some_attribute_of_the_data,
                             e.args[0].some_other_attribute_of_the_data)


class SomeUsersClass(myproject.UserClassTemplate):
    def project_method(self, data_passed_by_project):
        #want to test data_passed_by_project in here
        raise PassItUpForTesting(data_passed_by_project)
</code></pre>

<p>(For some reason, defining the custom exception within the same file wasn't working because the instance of the exception created within the user's class was not being identified as an instance of the custom exception.  Inspection of the exception via <code>sys.exc_*</code> revealed that the exception types were coming out differently.  So instead I put the exception in another module, import it, and it worked.)</p>

python class python-unittest