I can't seem to be able to mock the behaviour of a form when unit testing views.
My form is a simple ModelForm and resides in profiles.forms
. The view is (again) a simple view that checks whether the form is valid and then redirects.
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from profiles.forms import ProfileForm
def home(request):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
profile = form.save()
return HttpResponseRedirect(reverse("thanks"))
My test looks like this:
class TestViewHomePost(TestCase):
def setUp(self):
self.factory = RequestFactory()
def test_form(self):
with mock.patch('profiles.views.ProfileForm') as mock_profile_form:
mock_profile_form.is_valid.return_value = True
request = self.factory.post(reverse("home"), data={})
response = home(request)
logger.debug(mock_profile_form.is_valid.call_count) # "0"
is_valid
is not being called on the mock, which means ProfileForm is not patched.
Where did I make a mistake?
You should mock an object when you have a dependency in a unit of code you are trying to test that needs to be "just so".
In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test. Mocking makes sense in a unit testing context.
Automated testing during software development involves many different techniques, one that shouldn't be used is mocking. Mocks are a distraction at best and provide false confidence at worst.
Many mocking frameworks for Java code work in combination with JUnit and other popular unit testing frameworks, and are great depending on your specific needs. Two of the most widely used are Mockito and PowerMock. Mockito is useful for all but the most complicated cases, for which you can use PowerMock instead.
I was able to fix mocking is_valid
as following:
def test_form(self):
with mock.patch('profiles.views.ProfileForm.is_valid') as mock_profile_form:
mock_profile_form.return_value = True
request = self.factory.post(reverse("home"), data={})
response = home(request)
note: and you could use mock_profile_form.assert_called_once()
to check if the mock has been called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With