FrostyX
FrostyX

Reputation: 478

Dependency injection on data objects

I started writing tests for my (python) application and I found dependency injection very helpful. I refactored lot of my code, and it was so easy to write tests. But some classes was tricky.

I have class Application which is data structure containing attributes like name, type, etc. It have also few methods returning somehow modified those attributes. No problem with that, but there is an method instances (obviously) returning instances of the application in a form of list of Process objects.

class Application(object):
    ...
    def instances(self):
        return Processes.all().filtered(lambda process: process.name() == self.name)

You can see the dependency on Processes class. What should I do?

I have implemented it this way, because when I got an Application object from somewhere, I can simply call a.instances(), got the list of processes and don't care.

But from testing point of view, I would like to say "hey application, don't search for real processes in the system, look in this mocked processes list".

First possible solution which comes to my mind, was

def instances(self, processes=None):
    processes = processes if processes else Processes.all()
    return processes.filtered(...)

but it kind of means that probably all of my calls will have specified that argument. And a.instances(some_processes_list) is not that pretty as a.instances() and may be confusing. Would you consider it as confusing?

What approach or pattern would you recommend please?

Upvotes: 2

Views: 164

Answers (1)

Alvaro
Alvaro

Reputation: 12037

You could have the processes class as a class attribute:

class Application(object):
    process_class = Processes
    ...
    def instances(self):
        return self.process_class.all().filtered(lambda process: process.name() == self.name)

And assign a mock class to it (TestProcess) for testing (of course, this new class should implement the method 'all' and return your mock list).

This seems like a quite clear and natural way that doesn't involve patching or adding new methods

Upvotes: 1

Related Questions