It’s really difficult for me to manage updates on forms and related unit tests and I would really appreciate some feedback!
I have a Company model, and related very simple CompanyForm:
class CompanyForm(forms.ModelForm):
company_name = forms.CharField(label="Société", disabled=True)
class Meta:
model = Company
exclude = []
The view is very simple too:
@user_passes_test(lambda u: u.is_superuser or u.usercomp.is_admin)
def adm_options(request, comp_slug):
'''
Manage Company options
'''
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())
This view works fine, I can update information as I want (it’s actually not used for creation, which is done thanks to the Django Admin panel).
Unfortunately, I’m not able to build unit tests that will ensure update works!
I tried 2 ways, but none of them worked.
My first try was the following:
class TestOptions(TestCase):
def setUp(self):
self.company = create_dummy_company("Société de test")
self.user_staff = create_dummy_user(self.company, "staff", admin=True)
self.client.force_login(self.user_staff.user)
def test_adm_options_update(self):
# Load company options page
url = reverse("polls:adm_options", args=[self.company.comp_slug])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "0123456789")
self.assertEqual(self.company.siret, "0123456789")
# Options update
response = self.client.post(
reverse("polls:adm_options", args=[self.company.comp_slug]),
{"siret": "987654321"}
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "987654321")
self.assertNotContains(response, "0123456789")
self.assertEqual(self.company.siret, "987654321")
In this case, everything is OK but the latest assertion. It looks that the update has not been saved, which is actually not the case. I tried to Read the database just before (using my own get_company()
method, or even refresh_from_db()
), but it remains the same.
Here is my second try, built thanks to information found on the web, even if the approach surprised me a bit because I do not see how the view is actually tested (setUp()
remains the same):
def test_adm_options_update(self):
# Load company options page
url = reverse("polls:adm_options", args=[self.company.comp_slug])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "0123456789") # this is the default value in tests for this field
self.assertEqual(self.company.siret, "0123456789")
# Options update
self.company.siret = "987654321"
comp_form = CompanyForm(instance=self.company)
self.assertTrue(comp_form.is_valid())
comp_form.save()
company = Company.get_company(self.company.comp_slug)
self.assertEqual(company.siret, "987654321")
In this case, the form is just empty!
I could consider my view works and go ahead, but I would like to understand what’s wrong. And, to be honest, I have a bug in another view and I would like to ensure I can build the test to find out the bug.
Many thanks in advance for your answers!