Home > database >  TypeError while testing answer checker
TypeError while testing answer checker

Time:12-24

I'm writing a test for my "answer checker", so I made a test question and I want to test if the result checker works by giving the right answer (so the test should pass).

I'm in some trouble with the error that I got back. I know the code it's not that good, but I'm new in this field. I think I've misunderstood something in the logic. Can anybody help? :)

Error is:

correct = QuestionMultipleChoice.correct_answer()
      TypeError: 'property' object is not callable

Test (the last lines are wrong I know):

@when(u'I give an answer to a Multiple choice question')
def save_object(context):
    lab1 = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
    question1 = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)        

@then(u'I should get true if answer is correct')
def should_have_only_one_object(self):
    given = 1
    correct = QuestionMultipleChoice.correct_answer()
    QuestionMultipleChoice.check_answer(correct, given)
    assert 1 == Lab.objects.count()

Models.py

class QuestionMultipleChoice(models.Model):
    lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
    type = QuestionType.multiplechoice
    question = models.CharField(max_length=200,null=True)
    option1 = models.CharField(max_length=200,null=True)
    option2 = models.CharField(max_length=200,null=True)
    option3 = models.CharField(max_length=200,null=True)
    option4 = models.CharField(max_length=200,null=True)
    answer = models.IntegerField(max_length=200,null=True)
    
    def __str__(self):
        return self.question

    @property
    def html_name(self):
        return "q_mc_{}".format(self.pk)

    @property
    def correct_answer(self):
        correct_answer_number = int(self.answer)
        correct_answer = getattr(self, "option{}".format(correct_answer_number))
        return correct_answer

    def check_answer(self, given):
        return self.correct_answer == given

Update:

I followed youer hints (thank you) but still have some issue (the same one), plus, how can i access the object if it's defined in another function?

@when(u'I save the question in the lab 1')
def save_object(context):
    lab1 = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
    question1 = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)        

@then(u'I should get true if answer is correct')
def should_have_only_one_object(self):
    given = 1
    correct = QuestionMultipleChoice.correct_answer
    question1.check_answer(correct, given)
    assert 1 == Lab.objects.count()

CodePudding user response:

You just need to remove the parenthesis after correct_answer as it is a property, not a method.

Try:

@then(u'I should get true if answer is correct')
def should_have_only_one_object(self):
    given = 1
    correct = QuestionMultipleChoice().correct_answer
    QuestionMultipleChoice.check_answer(correct, given)
    assert 1 == Lab.objects.count()

Update

Here is an easy implementation using django's TestCase. See more in the docs

from django.tests import TestCase


class QuestionTestCase(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.lab = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
        cls.question = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)
        cls.answer = cls.question.correct_answer
    
    def test_check_answer(given=1):
        self.assertTrue(self.question.check_answer(self.answer, given))
    
    def test_lab_count():
        self.assertEqual(Lab.objects.count(), 1)
  • Related