Skip to main content

Pytest with Django

 


Steps and code to set up Django Rest Framework (DRF) test cases with database mocking.


 1. Set up Django and DRF


Install Django and DRF:

```sh

pip install django djangorestframework

```


Create a Django project and app:

```sh

django-admin startproject projectname

cd projectname

python manage.py startapp appname

```


2. Define Models, Serializers, and Views


models.py (appname/models.py):

```python

from django.db import models


class Item(models.Model):

    name = models.CharField(max_length=100)

    description = models.TextField()

```


serializers.py (appname/serializers.py):

```python

from rest_framework import serializers

from .models import Item


class ItemSerializer(serializers.ModelSerializer):

    class Meta:

        model = Item

        fields = '__all__'

```


views.py (appname/views.py):

```python

from rest_framework import viewsets

from .models import Item

from .serializers import ItemSerializer


class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()

    serializer_class = ItemSerializer

```


urls.py (appname/urls.py):

```python

from django.urls import path, include

from rest_framework.routers import DefaultRouter

from .views import ItemViewSet


router = DefaultRouter()

router.register(r'items', ItemViewSet)


urlpatterns = [

    path('', include(router.urls)),

]

```


projectname/urls.py:

```python

from django.contrib import admin

from django.urls import path, include


urlpatterns = [

    path('admin/', admin.site.urls),

    path('api/', include('appname.urls')),

]

```


3. Migrate Database and Create Superuser


```sh

python manage.py makemigrations appname

python manage.py migrate

python manage.py createsuperuser

python manage.py runserver

```


4. Write Test Cases


tests.py (appname/tests.py):

```python

from django.urls import reverse

from rest_framework import status

from rest_framework.test import APITestCase

from .models import Item

from .serializers import ItemSerializer


class ItemTests(APITestCase):

    

    def setUp(self):

        self.item1 = Item.objects.create(name='Item 1', description='Description 1')

        self.item2 = Item.objects.create(name='Item 2', description='Description 2')


    def test_get_items(self):

        url = reverse('item-list')

        response = self.client.get(url, format='json')

        items = Item.objects.all()

        serializer = ItemSerializer(items, many=True)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(response.data, serializer.data)


    def test_create_item(self):

        url = reverse('item-list')

        data = {'name': 'Item 3', 'description': 'Description 3'}

        response = self.client.post(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        self.assertEqual(Item.objects.count(), 3)

        self.assertEqual(Item.objects.get(id=3).name, 'Item 3')


    def test_update_item(self):

        url = reverse('item-detail', kwargs={'pk': self.item1.id})

        data = {'name': 'Updated Item 1', 'description': 'Updated Description 1'}

        response = self.client.put(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.item1.refresh_from_db()

        self.assertEqual(self.item1.name, 'Updated Item 1')


    def test_delete_item(self):

        url = reverse('item-detail', kwargs={'pk': self.item2.id})

        response = self.client.delete(url, format='json')

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        self.assertEqual(Item.objects.count(), 1)

```


5. Run Tests


```sh

python manage.py test

```


This setup provides a basic Django project with DRF and test cases for CRUD operations using the database. The test cases mock the database operations, ensuring isolation and consistency during testing.

Now diving into some more feature tests with Mock, patch etc.

Here are steps and code to write Django Rest Framework (DRF) test cases using mocking and faking features for scenarios like credit card processing.


1. Set up Django and DRF


Install Django and DRF:

```sh

pip install django djangorestframework

```


Create a Django project and app:

```sh

django-admin startproject projectname

cd projectname

python manage.py startapp appname

```


2. Define Models, Serializers, and Views


models.py (appname/models.py):

```python

from django.db import models


class Payment(models.Model):

    card_number = models.CharField(max_length=16)

    card_holder = models.CharField(max_length=100)

    expiration_date = models.CharField(max_length=5)

    amount = models.DecimalField(max_digits=10, decimal_places=2)

    status = models.CharField(max_length=10)

```


serializers.py (appname/serializers.py):

```python

from rest_framework import serializers

from .models import Payment


class PaymentSerializer(serializers.ModelSerializer):

    class Meta:

        model = Payment

        fields = '__all__'

```


views.py (appname/views.py):

```python

from rest_framework import viewsets

from .models import Payment

from .serializers import PaymentSerializer


class PaymentViewSet(viewsets.ModelViewSet):

    queryset = Payment.objects.all()

    serializer_class = PaymentSerializer

```


urls.py (appname/urls.py):

```python

from django.urls import path, include

from rest_framework.routers import DefaultRouter

from .views import PaymentViewSet


router = DefaultRouter()

router.register(r'payments', PaymentViewSet)


urlpatterns = [

    path('', include(router.urls)),

]

```


projectname/urls.py:

```python

from django.contrib import admin

from django.urls import path, include


urlpatterns = [

    path('admin/', admin.site.urls),

    path('api/', include('appname.urls')),

]

```


3. Migrate Database and Create Superuser


```sh

python manage.py makemigrations appname

python manage.py migrate

python manage.py createsuperuser

python manage.py runserver

```


4. Write Test Cases with Mocking and Faking


tests.py (appname/tests.py):

```python

from django.urls import reverse

from rest_framework import status

from rest_framework.test import APITestCase

from unittest.mock import patch

from .models import Payment

from .serializers import PaymentSerializer


class PaymentTests(APITestCase):


    def setUp(self):

        self.payment_data = {

            'card_number': '4111111111111111',

            'card_holder': 'John Doe',

            'expiration_date': '12/25',

            'amount': '100.00',

            'status': 'Pending'

        }

        self.payment = Payment.objects.create(**self.payment_data)

    

    @patch('appname.views.PaymentViewSet.create')

    def test_create_payment_with_mock(self, mock_create):

        mock_create.return_value = self.payment


        url = reverse('payment-list')

        response = self.client.post(url, self.payment_data, format='json')

        

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        self.assertEqual(response.data['card_number'], self.payment_data['card_number'])


    @patch('appname.views.PaymentViewSet.perform_create')

    def test_create_payment_fake_response(self, mock_perform_create):

        def fake_perform_create(serializer):

            serializer.save(status='Success')


        mock_perform_create.side_effect = fake_perform_create


        url = reverse('payment-list')

        response = self.client.post(url, self.payment_data, format='json')

        

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        self.assertEqual(response.data['status'], 'Success')


    def test_get_payments(self):

        url = reverse('payment-list')

        response = self.client.get(url, format='json')

        payments = Payment.objects.all()

        serializer = PaymentSerializer(payments, many=True)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(response.data, serializer.data)


    @patch('appname.views.PaymentViewSet.retrieve')

    def test_get_payment_with_mock(self, mock_retrieve):

        mock_retrieve.return_value = self.payment


        url = reverse('payment-detail', kwargs={'pk': self.payment.id})

        response = self.client.get(url, format='json')


        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(response.data['card_number'], self.payment_data['card_number'])


    @patch('appname.views.PaymentViewSet.update')

    def test_update_payment_with_mock(self, mock_update):

        mock_update.return_value = self.payment

        updated_data = self.payment_data.copy()

        updated_data['status'] = 'Completed'


        url = reverse('payment-detail', kwargs={'pk': self.payment.id})

        response = self.client.put(url, updated_data, format='json')


        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(response.data['status'], 'Completed')


    @patch('appname.views.PaymentViewSet.destroy')

    def test_delete_payment_with_mock(self, mock_destroy):

        mock_destroy.return_value = None


        url = reverse('payment-detail', kwargs={'pk': self.payment.id})

        response = self.client.delete(url, format='json')


        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        self.assertEqual(Payment.objects.count(), 0)

```


5. Run Tests


```sh

python manage.py test

```


This setup uses `unittest.mock.patch` to mock the behavior of various viewset methods in DRF, allowing you to simulate different responses without hitting the actual database or external services.

Comments

Popular posts from this blog

Financial Engineering

Financial Engineering: Key Concepts Financial engineering is a multidisciplinary field that combines financial theory, mathematics, and computer science to design and develop innovative financial products and solutions. Here's an in-depth look at the key concepts you mentioned: 1. Statistical Analysis Statistical analysis is a crucial component of financial engineering. It involves using statistical techniques to analyze and interpret financial data, such as: Hypothesis testing : to validate assumptions about financial data Regression analysis : to model relationships between variables Time series analysis : to forecast future values based on historical data Probability distributions : to model and analyze risk Statistical analysis helps financial engineers to identify trends, patterns, and correlations in financial data, which informs decision-making and risk management. 2. Machine Learning Machine learning is a subset of artificial intelligence that involves training algorithms t...

Wholesale Customer Solution with Magento Commerce

The client want to have a shop where regular customers to be able to see products with their retail price, while Wholesale partners to see the prices with ? discount. The extra condition: retail and wholesale prices hasn’t mathematical dependency. So, a product could be $100 for retail and $50 for whole sale and another one could be $60 retail and $50 wholesale. And of course retail users should not be able to see wholesale prices at all. Basically, I will explain what I did step-by-step, but in order to understand what I mean, you should be familiar with the basics of Magento. 1. Creating two magento websites, stores and views (Magento meaning of website of course) It’s done from from System->Manage Stores. The result is: Website | Store | View ———————————————— Retail->Retail->Default Wholesale->Wholesale->Default Both sites using the same category/product tree 2. Setting the price scope in System->Configuration->Catalog->Catalog->Price set drop-down to...

How to Prepare for AI Driven Career

  Introduction We are all living in our "ChatGPT moment" now. It happened when I asked ChatGPT to plan a 10-day holiday in rural India. Within seconds, I had a detailed list of activities and places to explore. The speed and usefulness of the response left me stunned, and I realized instantly that life would never be the same again. ChatGPT felt like a bombshell—years of hype about Artificial Intelligence had finally materialized into something tangible and accessible. Suddenly, AI wasn’t just theoretical; it was writing limericks, crafting decent marketing content, and even generating code. The world is still adjusting to this rapid shift. We’re in the middle of a technological revolution—one so fast and transformative that it’s hard to fully comprehend. This revolution brings both exciting opportunities and inevitable challenges. On the one hand, AI is enabling remarkable breakthroughs. It can detect anomalies in MRI scans that even seasoned doctors might miss. It can trans...