Introduction

Welcome to the second lesson of our course on testing in Django REST Framework. In this lesson, we'll focus on an essential aspect of testing — mocking the database using fixtures. When testing, it's crucial to isolate the database to ensure that tests are repeatable and consistent. Fixtures allow us to load predefined data into the database, making it easy to test various scenarios without manually setting up data each time. By the end of this lesson, you'll understand how to create and use fixtures in your Django test cases. We’ll also introduce how to export your database state into a fixture file.

Recap of Setup

Before we dive into fixtures, let's quickly recap the core setup for our TODO application from the previous course.

We created a Django app named myapp and defined a Todo model. Here’s a brief code snippet to refresh your memory:

# project/myapp/models.py
from django.db import models

class Todo(models.Model):
    task = models.CharField(max_length=255)
    assignee = models.CharField(max_length=100)
    due_date = models.DateTimeField()
    completed = models.BooleanField(default=False)
    group = models.CharField(max_length=100)

This sets the stage for our lesson on using fixtures for testing.

Introduction to Fixtures

Fixtures in Django are a way to load a predefined data set into the database. They are especially helpful in testing because they ensure that each test runs with the same data set, providing consistency and reliability.

Why use fixtures?

  • Consistency: Ensures the same data set is used across different test runs.
  • Isolation: Helps to isolate the database for unit tests.
  • Convenience: Saves time since you don't need to set up test data manually.

Django supports several file formats for fixtures, including JSON, XML, and YAML. In this lesson, we’ll use the JSON format.

Creating a Fixture File

Let's create a fixture file for our TODO app. A fixture file in Django is a JSON file that contains a list of dictionaries, each representing a record in the database.

Here’s an example fixture file:

[
    {
        "model": "myapp.todo",
        "pk": 1,
        "fields": {
            "task": "Mock task 1",
            "assignee": "John Doe",
            "due_date": "2023-12-31T23:59:59Z",
            "completed": true,
            "group": "Group A"
        }
    },
    {
        "model": "myapp.todo",
        "pk": 2,
        "fields": {
            "task": "Mock task 2",
            "assignee": "Jane Smith",
            "due_date": "2023-11-30T23:59:59Z",
            "completed": false,
            "group": "Group B"
        }
    }
]

Explanation:

  • Each entry in the list represents a record in the Todo model.
  • model specifies which model the data belongs to. This key must match the model name in your Django application, specified as app_name.model_name. Changing this key will result in errors as Django will not be able to recognize the model.
  • pk is the primary key of the record, which is the item's id. Changing this key's name or value will break the relationship of the data with the model.
  • fields contains the values for the fields in the model. If you define fields wrong, such as passing None for a non-nullable field, Django will raise a validation error and fail to load the fixture.
  • If you provide wrong field's types, such as assigning an integer value to the "completed" field, which expects a boolean, Django will automatically convert it. However, this could still lead to unexpected behavior if the conversion doesn't align with your expectations or not possible.
Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal