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?

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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 ...
It would be a class level attribute. Only the Application class would have the attribute. Check stackoverflow.com/questions/7809407/… for instance
Thank you @Alvaro, I've missed that. I am successfully using it, so I have marked your answer as the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.