I have a class that, when called, forms a connection to a database and enters some data into it. This class is passed to other objects in my program. But I want to test other functionality of my program without having to write to the database every time.
My solution is to make a dummy class that has the same methods as the primary class but which doesn’t actually talk to a database. That way all the other objects in the program can still keep their same functionality but I’ll have "disconnected" the database read/write options. If there’s an alternative way to do what I’m doing, I’d love to be informed of a best practice.
So I want to create a dummy class that has all the same methods as another class but with no functionality. For example, if I had the following class:
class Primary:
def foo(self, a, b):
return a+b
def bar(self, a, b):
return a-b
I want the dummy class to be:
class Dummy:
def foo(self, a, b):
pass
def bar(self, a, b):
pass
Is there a way to dynamically access all the method names in Primary and use them to create their dummy alternatives in Dummy? I could do this manually, but I’d love for Dummy to update automatically whenever I add new methods to Primary.
My first idea was to assign methods based on a variable, something like:
class Dummy:
def __init__(self):
method_list = [func for func in dir(Primary) if callable(getattr(Primary, func)) and not func.startswith("__")]
for m in method_list:
self.m = dummy_func
def dummy_func(self, *args):
pass
The idea for getting the methods from Primary comes from this question: How do I get list of methods in a Python class?
But of course you can’t assign a method based on a variable (or can you?). I was also wondering if there was a way for Dummy to inherit Primary but manually overwrite all of its methods, but haven’t figured out a way to do that yet.
>Solution :
Just like there is getattr, there is setattr.
It would probably be better to set the attributes on the Dummy class rather than on its instances, to make it match its behaviour more closely.
For example:
class Dummy:
def dummy_func(self, *args):
pass
for attr in dir(Primary):
if callable(getattr(Primary, attr)) and not attr.startswith("__"):
setattr(Dummy, attr, Dummy.dummy_func)
As @jonrsharpe pointed out in a comment, if this is used for testing, you might prefer Mock instead.