Reputation: 526
I want to use dependency injection for my django project. For that I'm trying pinject package. Like in ASP.NET, all the dependencies are given in the constructor, and that's very nice because it's easy to test. I would also like to archive something similar in my django project.
I have a simple View:
class MySimpleView(View):
def __init__(self, dependency1, dependency2, **kwargs):
super().__init__(**kwargs)
...
A place where I define the bindings
# di.py
class AppBindingSpec(pinject.BindingSpec):
def configure(self, bind):
# do the bindings here
obj_graph = pinject.new_object_graph(binding_specs=[AppBindingSpec()])
And I expected to use it like this.
# urls.py
urlpatterns = [
path('path/to/my/view', obj_graph.provide(MySimpleView).as_view()),
]
But unfortunately, django does not allow the .as_view()
to be called from an instance.
Is there any simple way to inject the dependencies into my view so I can easily mock and test?
Upvotes: 2
Views: 2498
Reputation: 485
If your goal is to provide yourself with an easy and safe way to 'mock and test', then you are probably better of using the mock library provided by unittest
(which by the way is also a lot like mocking in .NET). With this, you can do something like this:
from unittest.mock import Mock, patch
from django.tests import TestCase
class MySimpleViewTestCase(TestCase):
@patch('module_name.dependency2')
@patch('module_name.dependency1.specific_method_or_attribute')
def test_something_about_mysimpleview(self, mock_dependency1, mock_dependency2):
mock_dependency1.return_value = Mock(some_attribute="foo", some_method.return_value="bar")
mock_dependency2.return_value = 42
# do your testing of MySimpleView
Now, when the test runs, mock
will replace whatever module_name.dependency1.specific_method_or_attribute
and module_name.dependency2
was with mock objects. So, when module_name.dependency2()
is run, it will return 42
, while specific_method()
will return a Mock
object with an attribute with the value "foo"
and a method some_method()
that returns "bar"
.
You can use this to mock functions, classes or even modules.
Upvotes: 2