Юнит-тест для формы обновления Django
Я не понимаю, как управлять обновлениями форм и связанных с ними модульных тестов, и буду очень признателен за советы =)
.У меня есть модель компании, и связанная с ней очень простая форма CompanyForm:
class CompanyForm(forms.ModelForm):
company_name = forms.CharField(label="Société", disabled=True)
class Meta:
model = Company
exclude = []
Вид тоже очень прост:
@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())
Это представление работает нормально, я могу обновлять информацию (на самом деле оно не используется для создания, что делается благодаря панели Django Admin).
К сожалению, мне не удается создать модульные тесты, которые гарантируют, что обновление работает!
Я попробовал 2 способа, но ни один из них не сработал. Моя первая попытка была следующей:
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")
В данном случае все в порядке, кроме последнего утверждения. Похоже, что обновление не было сохранено, что на самом деле не так. Я попытался считать базу данных как раньше, с ключом, сохраненным в контексте, но все осталось по-прежнему.
I was looking for other information when I found this topic, so I tried another way to test, even if the approach surprised me a bit (I do not see how the view is actually tested).
Here is my second try (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")
В этом случае форма просто пуста!
Я могу считать, что мое представление работает, и идти дальше, моя проблема в том, что у меня есть ошибка в другом представлении, и я хотел бы убедиться, что могу создать тест, чтобы обнаружить ошибку!
Заранее большое спасибо за ваши ответы!
В этом случае вам нужно использовать refresh_from_db
для "обновления" вашего объекта, как только представление и форма закончат обновление вашего объекта. Это означает, что при текущем утверждении вы используете "старый снимок" self.company
, отсюда и сбой при утверждении, поэтому вам нужно обновить его:
# Options update
response = self.client.post(
reverse("polls:adm_options", args=[self.company.comp_slug]),
{"siret": "987654321"}
)
...
self.company.refresh_from_db()
self.assertEqual(self.company.siret, "987654321")