Testing Private Methods in Python (An Exception)

Python does some name mangling when it puts the actually-executed code together. Thus, if you have a private method __A on MyClass, you would need to run it like so in your unit test:

from unittest import TestCase

class TestMyClass(TestCase):
    def test_private(self):
        expected = 'myexpectedresult'
        m = MyClass()
        actual = m._MyClass__A
        self.assertEqual(expected, actual)

The question came up about so-called 'protected' values that are demarcated by a single underscore. These method names are not mangled, and that can be shown simply enough:

from unittest import TestCase

class A:

    def __a(self):
        return "myexpectedresult"

    def _b(self):
        return "a different result"


class TestMyClass(TestCase):

    def test_private(self):
        expected = "myexpectedresult"
        m = A()
        actual = m._A__a()
        self.assertEqual(expected, actual)

    def test_protected(self):
        expected = "a different result"
        m = A()
        actual = m._b()
        self.assertEqual(expected, actual)
        # actual = m._A__b() # Fails
        # actual = m._A_b()  # Fails

First of all, you CAN access the "private" stuff, can't you? (Or am I missing something here?)

>>> class MyClass(object):
...     def __init__(self):
...             pass
...     def __A(self):
...             print('Method __A()')
... 
>>> a=MyClass()
>>> a
<__main__.MyClass object at 0x101d56b50>
>>> a._MyClass__A()
Method __A()

But you could always write a test function in MyClass if you have to test the internal stuff:

class MyClass(object):
    ...
    def _method_for_unit_testing(self):
        self.__A()
        assert <something>
        self.__B()
        assert <something>
        ....

Not the most elegant way to do it, to be sure, but it's only a few lines of code at the bottom of your class.