2

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?

dbugger
  • 15,868
  • 9
  • 31
  • 33
FrostyX
  • 358
  • 3
  • 10

1 Answers1

1

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

Alvaro
  • 11,797
  • 9
  • 40
  • 57
  • Thank you. I thought about this way too, but it felt unnatural. Because there are lot of `Application` objects and `Processes` class is always same. Even so every application would has its own `Processes` instance. Its surely better than what I have right now because it is easily testable, but ... – FrostyX Feb 24 '15 at 19:10
  • It would be a class level attribute. Only the Application class would have the attribute. Check http://stackoverflow.com/questions/7809407/attributes-initialization-declaration-in-python-class-where-to-place-them for instance – Alvaro Feb 24 '15 at 19:18
  • Thank you @Alvaro, I've missed that. I am successfully using it, so I have marked your answer as the solution. – FrostyX Mar 12 '15 at 10:05