Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete (tearDown) a singleton instance decorator in Python for unit testing?

I am new to Python. I have a singleton decorator defined as:

def singleton(cls):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

And my Singleton class:

@singleton
class MyClass:

    def __init__(self, **kwargs):
        self.config = None
        ...

I wanto to write some unit tests for MyClass but I need to destroy it on the tearDown() method so that the tests run ok. How can I do it?

Many thanks,

like image 455
void Avatar asked Mar 07 '26 18:03

void


1 Answers

I think the question could be re-asked as "Can I access closure variables outside closure" to clear the ìnstances` dict.

I have not tested this, but this approach could work where you expose instances data as a function attribute (basically making it equal to module level variable):

def singleton(cls):

    def getinstance():
        if cls not in singleton.instances:
            singleton.instances[cls] = cls()
        return singleton.instances[cls]
    return getinstance

singleton.instances = {}


# Then clear
def tearDown(self):
    singleton.instances = {}

However I am not sure if you want to go through all the magic just to have a singleton. E.g. alternative, less magical, lazy loading pattern could be:

class MyClass:

     @classmethod
     def get_instance(cls):
         if not hasattr(cls, "_instance"):
             cls._instance = cls()
         return cls._instance

instance = MyClass.get_instance()

Or even simpler without lazy loading:

class MyClass:
    ...


MyClass.instance = MyClass()
like image 66
Mikko Ohtamaa Avatar answered Mar 09 '26 06:03

Mikko Ohtamaa