Create random data for your Django unit tests using Model Mommy

June 11, 2019 - IT

What do you use for creating test data?

Let's say we have a simple user model.

from django.db import models


class User():
    email = models.EmailField(unique=True, max_length=255)
    first_name = models.CharField(max_length=255)
    birthday = models.DateField(models.Model)

You can create own method to generate users in unit tests and use Faker to generate random data.

from faker import Faker

from users.models import User


fake = Faker()

class UserTestCaseMixin:
    def _create_user(self, email=None, first_name=None, birthday=None):
        return User.objects.create(
          email=email or fake.ascii_safe_email(),
          first_name=first_name or fake.first_name_female(),
          birthday=birthday or fake.date_of_birth(),
        )

It's not the worst way but it requires creating separate methods for each model.

The easier way is to use a ready library, like Model Mommy.

Look at this simple example:

from model_mommy import mommy


def test_create_user():
    user = mommy.make('users.User')

Single line and the random user is ready to use!

Do you want to create more users?

from model_mommy import mommy


def test_create_user():
    user = mommy.make('users.User', _quantity=3)

There is one small issue. The first_name field is a CharField with max_length=255. Model Mommy will create a random string with maximum length (255 characters). Sometimes you may need a better value like a real first name. You can use Recipe to achieve this.

from faker import Faker
from model_mommy.recipe import Recipe, seq

from .models import User

fake = Faker()


user = Recipe(
    User,
    first_name=fake.first_name(),
)

To generate a user from the recipe, use make_recipe instead of make.

from model_mommy import mommy


def test_create_user():
    user = mommy.make_recipe('users.User')

You can even simply overwrite selected model properties.

mommy.make('users.User', email='[email protected]')

These are just simple examples. You can find more features in the documentation.