I spent quite a lot of time to set some unit test, and one of the issues was the setting of some fields that I defines to be nullable and blankable. Putting dummy values was not an issue, but I wonder: how to deal with fields that need to be blank, in particular for numbers?
Let me write as an example an extract of my code.
The model:
class Company(models.Model):
company_name = models.CharField("nom", max_length=200)
comp_slug = models.SlugField("slug")
street_num = models.IntegerField("N° de rue", null=True, blank=True)
street_cplt = models.CharField("complément", max_length=50, null=True, blank=True)
address = models.CharField("adresse", max_length=300)
The form:
class CompanyForm(forms.ModelForm):
company_name = forms.CharField(label="Société", disabled=True)
class Meta:
model = Company
exclude = []
The view:
def adm_options(request, comp_slug):
company = Company.get_company(comp_slug)
comp_form = CompanyForm(request.POST or None, instance=company)
if request.method == "POST":
if comp_form.is_valid():
comp_form.save()
return render(request, "polls/adm_options.html", locals())
A very simple unit test:
def create_dummy_company(name):
return Company.objects.create(
company_name=name,
comp_slug=slugify(name),
street_num=1,
street_cplt='',
address='dummy address'
)
def test_adm_options_update(self):
self.company = create_dummy_company("Test company")
url = reverse("polls:adm_options", args=[self.company.comp_slug])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.company.address = 'new address'
response = self.client.post(
reverse("polls:adm_options", args=[self.company.comp_slug]),
self.company.__dict__,
)
self.company.refresh_from_db()
self.assertEqual(response.status_code, 200)
Of course, the key part is posting the form after the update. The different cases I met were the following:
- No problem with the test as written above
- If I omit one of the fields (
street_num
orstreet_cplt
), the post raisesTypeError: Cannot encode None as POST data. Did you mean to pass an empty string or omit the value?
This is my main issue as far as no error should be raised if one field stays blank - Anyway, in this case, what about number fields? How can I set
street_num
to blank? If I trystreet_num=''
, it raises a Value error:ValueError: invalid literal for int() with base 10: ''
So how could I deal with that for, for example, build a unit test that checks that I can post a form with no values for each single field set to null=True, blank=True
?