Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking forms in view unit tests

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?

like image 645
LaundroMat Avatar asked Apr 23 '17 12:04

LaundroMat


People also ask

What should be mocked in unit tests?

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".

Should I mock everything in unit tests?

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.

Is mocking bad in unit testing?

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.

What mocking frameworks have you used for unit testing?

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.


1 Answers

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.

like image 75
udo Avatar answered Sep 20 '22 16:09

udo