Nathan Tregillus
Nathan Tregillus

Reputation: 6344

how do you test private static method in module in python

we have a module of static methods in our python app. these methods use a lot of private (e.g: "__do_sub_task2(**args)") I would like to write unit tests for these private static methods within this module, but I am getting refernce errors.

is there a way to do this?

update: adding scenario

I have a module file named 'my_module.py' contents of said file is as follows:

def public_method_foo(my_number):
  return __sub_method_bar(my_number * 10)

def __sub_method_bar(other_number)
  return other_number + 11

update #2 The reason I am asking this question is because I have a similar scenario as above, but when I add the following reference to my test.py module file:

from my_module import __sub_method_bar

and try to use it in my test, I get the following exception in my test

global name '_MyTests__sub_method_bar' is not defined

Upvotes: 3

Views: 3946

Answers (1)

abarnert
abarnert

Reputation: 365925

What you have are not methods, not private, and not static; they're just plain old public functions in the module. So you call them the same way as any other function. For your example:

>>> my_module.__sub_method_bar(5)

That's it; nothing tricky.*

* Well, there is one tricky thing, but it's probably not going to affect you here: If my_module doesn't have an __all__, and you do from my_module import *, you will not get any of the globals (including functions) whose names start with _. But normally your unit tests are going to import my_module, so this won't be relevant.


Methods are callables that are members of a class. And methods can be private ("private" in this sense means "visible only to this class, not even to super- or sub-classes", so it doesn't make sense for anything but methods). The tutorial chapter on Classes explains how private methods are implemented, with name-mangling. Methods (private or otherwise) can also be static ("static" in this context means "does not take the normal self", so again, it doesn't make sense for anything but methods). Either way, for a private method, you have to manually demangle the name to call it from outside:

>>> thingy = Thingy()
>>> thingy._Thingy__private_method(5)
>>> Thingy._Thingy__private_static_method(5)

Upvotes: 5

Related Questions