Home > Software design >  How to test if an instance of a django model was created?
How to test if an instance of a django model was created?

Time:02-13

I am testing an api for a game and have some issues with a model.

This is my model:

models.py

class Gamesession(models.Model):
    gamemode = models.ForeignKey(Gamemode, on_delete=models.CASCADE, null=True)
    user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    gametype = models.ForeignKey(Gametype, on_delete=models.CASCADE)
    created = models.DateTimeField(editable=False)

    objects = models.Manager()

This is the test suite:

test_models.py

    def setUp(self):
        self.user = CustomUser.objects.create(id=1, username="carina")
        self.gametype = Gametype.objects.create(id=1, name="NewGame", rounds=5, round_duration=60, enabled=True)
        self.gamesession_user = self.user
        self.gamesession_gametype = self.gametype
        self.gamesession_created = datetime.utcnow().replace(tzinfo=pytz.UTC)
        self.gamesession = Gamesession.objects.create(id=1,
                                                      user=self.gamesession_user,
                                                      gametype=self.gamesession_gametype,
                                                      created=self.gamesession_created)

    def test_create_gamesession(self):
        gamesession = Gamesession.objects.create(gametype=self.gametype)
        assert gamesession.gametype == self.gamesession_gametype

Running my tests keeps retrieving the error: GamesessionTests::test_create_gamesession - django.db.utils.IntegrityError: null value in column "created" of relation "frontend_games

How can I solve this? Is there a better way to test if an instance of the model is created?

CodePudding user response:

This happens because you defined created as a field that is not null=True and without any default=…, so that means that it does not assign a proper value to it. You thus can construct the object with:

def test_create_gamesession(self):
    gamesession = Gamesession.objects.create(
        gametype=self.gametype,
        gamesession_created=self.gamesession_created
    )
    assert gamesession.gametype == self.gamesession_gametype

You probably do not want to specify a value anyway, you can make use of auto_now_add=True [Django-doc] to specify that Django should fill in the timestamp when creating the object:

class Gamesession(models.Model):
    # …
    created = models.DateTimeField(auto_now_add=True)

this will also make the field non-editable.

  • Related