Somewhat based on a chapter of this book, I'd like to unit test a form created with django-crispy-form but I get the following error:
TypeError: helper object provided to {% crispy %} tag must be a crispy.helper.FormHelper object.
The form (myapp/forms.py):
class MyBaseForm(forms.models.ModelForm):
def __init__(self, *args, **kwargs):
super(MyBaseForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-myForm'
self.helper.form_method = 'POST'
self.helper.form_action = ''
self.helper.add_input(Submit('submit', 'Create'))
class Meta:
model = MyModel
# [...]
class MyNewForm(MyBaseForm):
def save(self):
return MyModel.create_new(data=self.cleaned_data['data'])
The view (myapp/views.py):
@login_required
def event_new(request):
if request.method == 'POST':
form = MyNewForm(data=request.POST)
if form.is_valid():
event = form.save()
return redirect(event)
else:
form = MyNewForm()
return render(request, 'event_new.html', {'form': form})
The test:
@patch('myapp.views.MyNewForm')
class MyNewViewUnitTest(TestCase):
def setUp(self):
self.t = unittest.TestCase()
self.t.request = HttpRequest()
self.t.request.POST['data'] = 'data'
self.t.request.user = Mock()
def test_passes_POST_data_to_Form(self, mockMyNewForm):
event_new(self.t.request)
mockMyNewForm.assert_called_once_with(data=self.t.request.POST)
Do I somehow have to mock the helper object as well? And how would that be done? Thank you very much!
Late answer, but ran up against this today. You need to spec the helper for your mock class to the FormHelper so that the "isinstance" call in the crispy templates passes. Easiest way to do this is to create a MagicMock subclass for the crispy form:
class MockCrispyForm(MagicMock):
helper = MagicMock(spec=FormHelper)
helper.template = False # necessary for templates to render
def is_valid(self):
return True # optional if you want form to validate
@patch('myapp.views.MyNewForm', MockCrispyForm())
class MyNewViewUnitTest(TestCase):
def setUp(self):
self.t = unittest.TestCase()
self.t.request = HttpRequest()
self.t.request.POST['data'] = 'data'
self.t.request.user = Mock()
def test_passes_POST_data_to_Form(self):
event_new(self.t.request)
myapp.views.MyNewForm.assert_called_once_with(
data=self.t.request.POST
)
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