I use Django 2.1
on python 3.6
with pytest-django 3.4
I like to test the clean()
method of a form defined like this :
from django.forms import HiddenInput, ModelForm, ValidationError
from log.models import Entry
class EntryForm(ModelForm):
class Meta:
model = Entry
fields = ['user', 'contact', 'title', 'desc']
widgets = {
'user': HiddenInput(),
'contact': HiddenInput(),
}
def __init__(self, *args, **kwargs):
""" Get back user & contact obj for `self.clean()` """
user = kwargs.pop('user')
contact = kwargs.pop('contact')
super(EntryForm, self).__init__(*args, **kwargs)
self.fields['user'].initial = user
self.fields['contact'].initial = contact
def clean(self):
"""
Checks if a entry is added on a contact owned by the connected user
"""
cleaned_data = super(EntryForm, self).clean()
if 'user' in self.changed_data or 'contact' in self.changed_data:
raise ValidationError("Hidden input changed")
if cleaned_data['contact'].user != cleaned_data['user']:
raise ValidationError("Not allowed")
Outside tests, in a browser, this work as charm even if I change the values of hidden inputs : the ValidationError
is raised.
I think about using monkeypatch
but I did not understand how to inject my test conditions in a django class…
I use my feelings to build this test, but I cannot raise the expected ValidationError
:
def fake_entry_form__init__():
self.fields['user'].initial = 'initial user'
self.fields['contact'].initial = 'initial contact'
def fake_entry_form_unvalid_changed_data():
return {
'user': 'foo user',
'contact': 'foo contact'
}
def test_entry_form_clean_unvalid(monkeypatch):
monkeypatch.setattr('log.forms.EntryForm.__init__', fake_entry_form__init__)
form = EntryForm
monkeypatch.setattr('log.forms.EntryForm.changed_data', fake_entry_form_unvalid_changed_data)
try:
form.clean
assert False
except KeyError:
assert True
Am I on a good track or completely wrong?
I am new in django, CBV & testing, this is maybe a very obvious case, but I did not find explanation about it.
Aucun commentaire:
Enregistrer un commentaire