how to test a model that has a foreign key in django?
Asked Answered
B

3

12

I'm using python 3.5 and Django 1.10 and trying to test my app in tests.py, but an error appeared, it said: ValueError: Cannot assign "1": "NewsLetter.UserID" must be a "User" instance. so how to test a fk value here? here is the code:

class NewsletterModelTest(TestCase):

    @classmethod
    def setUpTestData(cls):
        #Set up non-modified objects used by all test methods
        NewsLetter.objects.create(NewsLetterID=1, Email='[email protected]', Connected=False,UserID=1)


    class NewsLetter(models.Model):
         NewsLetterID = models.AutoField(primary_key=True)
         Email = models.CharField(max_length=255)
         Connected = models.BooleanField(default=False)
         UserID = models.ForeignKey(User, on_delete=models.CASCADE)
         class Meta:
              db_table = 'NewsLetter'
Brittan answered 17/6, 2017 at 12:31 Comment(0)
W
18

In your setupTestData method you have to create a User object, and pass it into the NewsLetter object create method.

@classmethod
def setUpTestData(cls):
    #Set up non-modified objects used by all test methods
    user = User.objects.create(<fill params here>)
    NewsLetter.objects.create(NewsLetterID=1, Email='[email protected]', Connected=False,UserID=user)
Wakashan answered 17/6, 2017 at 12:42 Comment(2)
the thing is user also has more than one fk field, so does this mean I have to add model.objects.create to all models I will use in every class?Brittan
you have to create the object first to pass it to any class that has fk field. There is no other way around thisWakashan
H
4

For those who land here.

To write a test for a model that has a ForeignKey field, you need to create an instance of the model that the ForeignKey points to and then call save() on the ForeignKey instance, before applying it to the creation of your target model for the test.

eg. (simplified for brevity)

class BookTestCase(TestCase):
    def test_fields_author_name(self):
        author = Author(name="Mazuki Sekida")
        author.save()
        book = Book(name="Zen Training", author=author)
        book.save()

        # assertion example ...
        record = Book.objects.get(id=1)
        self.assertEqual(record.author.name, "Mazuki Sekida")         
Homeric answered 26/10, 2019 at 14:14 Comment(0)
U
1

Very similar to what @Arpit Solanki answered, here's what I did:

from datetime import date

from django.test import TestCase

from ..models import Post, Author


class PostModelTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.author_ = 'Rambo'
        cls.author = Author.objects.create(name=cls.author_)
        cls.post = Post.objects.create(
            title='A test', author=cls.author, content='This is a test.', date=date(2021, 6, 16))

    def test_if_post_has_required_author(self):
        self.assertEqual(self.post.author.name, self.author_)
Uropygium answered 16/6, 2021 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.