在Django应用程序中测试视图

时间:2014-08-02 20:31:36

标签: python django functional-testing

models.py中的模型很少。其中两个如下:

class Event():
      eventName = models.CharField( unique = True )

class Job():
      event = models.ForeignKey(Event)
      jobName = models.CharField

      class Meta:
          unique_together(('event','jobName'))

我正在使用Client module中的django.test来测试此类的模型形式。我失败的测试是在测试unique_together属性

以下是我的test.py

class TestJobView(TestCase):
    def test_duplicate_job_in_same_event(self):
        Event.objects.create(eventName='test_event', noOfVolunteersRequired=10,
                startDate='2014-05-05 05:05:05', endDate='2014-05-05 05:05:05')

        Job.objects.create(event=Event.objects.get(eventName='test_event'),
                   jobName='test_jobName',jobDescription='test_jobDescription_1',
                   noOfVolunteersRequired=10, startDate='2014-05-05 05:05:05', 
                   endDate='2014-05-05 05:05:05')
        self.assertEqual(1, Job.objects.filter(event__eventName='test_event', 
                           jobName='test_jobName').count())

        c = Client()

        response = c.post('/AdminUnit/job/',{'event' : 'test_event',
        'jobName' : 'test_jobName','jobDescription' : 'test_jobDescription_2',
        'startDate' : '2014-05-05 05:05:05', 'endDate' : '2014-05-05 05:05:05', 
        'noOfVolunteersRequired' : 5})

        self.assertEqual(200, response.status_code)
        print response.context['jobsForm']['event'].errors

上述测试的结果打印Select a valid choice. That choice is not one of the available choices.

现在,我有两个问题。首先,不应该因为事件已经创建而引发此异常,并且在上述方法中也是asserted True。其次,如果我从我的观点中尝试相同的事情,它会引发non_field_error并说Job with this Event and JobName already exists.。如何使用响应在我的tests.py中捕获它?

2 个答案:

答案 0 :(得分:3)

您不会显示您的观点或表单,但可能您只是使用默认的ModelForm,它将ForeignKey表示为ModelChoiceField。因此,发布event的值不是名称,而是在测试开始时创建事件时应捕获的ID。

但是,我应该补充一点,我认为你根本不应该对此进行测试。单元测试适用于您的代码,而不是Django。 unique_together是Django本身的一部分,因此Django自己的单元测试非常清楚。您无需明确复制该功能。

修改

我不理解你的第二条评论。您的测试应该如下所示:

def test_duplicate_job_in_same_event(self):
    event = Event.objects.create(...)
    job = Job.objects.create(event=event, ...)
    response = self.client.post('/AdminUnit/job/',{'event' : event.id, ...})

答案 1 :(得分:1)

Ad Daniel Roseman注意到,unique_together不应该在这里测试。如果它应该被测试是一个意见的主。但是,unique_together是在模型级别定义的,幸运的是,当您在那里进行单元测试时,一切都变得简单了:

class TestJob(TestCase):
    def test_duplicate_in_same_event(self):
        event = Event.objects.create(
            eventName='test_event', noOfVolunteersRequired=10,
            startDate='2014-05-05 05:05:05', endDate='2014-05-05 05:05:05')

        Job.objects.create(
            event=event,
            jobName='test_jobName',jobDescription='test_jobDescription_1',
            noOfVolunteersRequired=10, startDate='2014-05-05 05:05:05', 
            endDate='2014-05-05 05:05:05')

        job = Job(
            event=event,
            jobName='test_jobName',jobDescription='test_jobDescription_1',
            noOfVolunteersRequired=10, startDate='2014-05-05 05:05:05', 
            endDate='2014-05-05 05:05:05')

        with self.assertRaises(ValidationError):
            job.validate_unique()