@ARHAT-99

Как правильно тестировать views и models??

Новичек в django, вроде все окей но когда дело доходит до тестов то у меня появляются вопросы насчет того что я не так сделал, в каком-то коде или не правильно начал делать. P.S. Будет много кодов, но все равно надеюсь на вашу помощь
views.py
from django.shortcuts import render
from .forms import QueryForm
from .services.handler import gadget_handler, ProductNotFound
 
 
def detail(request):
    if request.method == "POST":
        form = QueryForm(request.POST)
        if form.is_valid():
            try:
                query_name = form.cleaned_data['query_name']
                result = gadget_handler(query_name)
                context = {'result': result}
                return render(request, 'polls/detail.html', context)
            except ProductNotFound:
                errors = "По запросу " + form.cleaned_data['query_name'] + " ничего не найдено"
                return render(request, 'polls/detail.html', {'errors': errors})
        else:
            errors = form.errors
            return render(request, 'polls/detail.html', {'errors': errors})
 
    return render(request, 'polls/detail.html')

test_views.py
test import TestCase, Client
from django.urls import reverse
from unittest.mock import patch
from ..exceptions import ProductNotFound
 
 
class TestViews(TestCase):
 
    def test_detail_GET(self):  # проверка шаблона
        client = Client()
        response = client.get(reverse('detail'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'polls/detail.html')
 
    @patch('polls.views.gadget_handler')
    def test_result_POST(self, mock_gadget_handler):  # если есть продукт
        mock_gadget_handler.return_value = [{
            'title': 'Мобильный Телефон Xiaomi Redmi Note 9 PRO (6+128Gb) Global EU',
            'price': 17100,
            'url': 'http://www.gadget.kg/catalog/telefony/xiaomi/3400'}]
        client = Client()
        response = client.post(reverse('detail'), {'query_name': 'xiaomi redmi note 9'})
        self.assertEqual(response.context['result'], mock_gadget_handler.return_value)
 
    @patch('polls.views.gadget_handler')
    def test_products_not_found(self, mock_gadget_handler):
        mock_gadget_handler.side_effect = ProductNotFound('Товар не найден')
        expected_exception = 'По запросу qwerty ничего не найдено'
        client = Client()
        response = client.post(reverse('detail'), {'query_name': qwerty'}) # как мне продолжить что-бы проверить его

models.py
from django.db import models
# Create your models here.
 
 
class Query(models.Model):
    query_name = models.CharField(max_length=100)
    datetime = models.DateTimeField(auto_now=True, editable=True)
 
    def __str__(self):
        return self.query_name
 
 
class Result(models.Model):
    title = models.CharField(max_length=255)
    cost = models.IntegerField()
    url = models.URLField(max_length=255)
    query = models.ForeignKey(Query, on_delete=models.CASCADE)
 
    def __str__(self):
        return self.title

test_models.py
from django.test import TestCase
from django.utils import timezone
from ..models import Query, Result
 
 
class TestQuery(TestCase):
 
    def test_query_creation(self):
        q = Query.objects.create(query_name='xiaomi redmi note 9', datetime=timezone.now())
        self.assertTrue(q.__str__(), q.query_name)
 
 
class TestResult(TestCase):
 
    def test_result_creation(self): # этот тест жалуется на модельки
        q = Query.objects.create(query_name='xiaomi redmi note 9')
        r = Result.objects.create(title='Мобильный Телефон Xiaomi Redmi Note 9 PRO (6+128Gb) Global EU',
                                  cost=17100,
                                  url='http://www.gadget.kg/catalog/telefony/xiaomi/3400',
                                  query=q)
        self.assertEqual(r.__str__(), r.title)

вот ошибка которую он мне говорит:
File "/home/rahat/PycharmProjects/untitled1/venv/lib/python3.6/site-packages/django/db/models/base.py", line 115, in __new__
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class products-aggregator.mysite.polls.models.Query doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

На всякий случай вот мой handler
from django.core.exceptions import ObjectDoesNotExist
from django.utils.timezone import utc
import datetime
 
from ..exceptions import ProductNotFound
from ..models import Query, Result
from .extractor import GadgetExtractor
from .transform import GadgetTransform
from .load_ver import GadgetLoader
import logging
 
logger = logging.getLogger('__name__')
 
 
def get_data_from_site(query_name):
    query_name = query_name.split()
    extractor = GadgetExtractor()
    link = extractor.get_product_link(name_list=query_name)
    page = extractor.get_html(url=link)
 
    transform = GadgetTransform()
    products = transform.get_data(html=page)
    return products
 
 
def load_date_into_database(products, query):
    loader = GadgetLoader()
    result = loader.load(products, query)
    return result
 
 
def gadget_handler(query_name):
    try:
        query_name = query_name.lower()
        query = Query.objects.get(query_name=query_name)
        now = datetime.datetime.utcnow().replace(tzinfo=utc)
        timediff = now - query.datetime
 
        if timediff.days > 1:
            logger.info('Update datetime')
            Query.objects.filter(query_name=query_name).update(datetime=now)
            logger.info("Query datetime updated")
 
            logger.info('Get data from site')
            result = get_data_from_site(query_name)
 
            logger.info('Delete data')
            Result.objects.filter(query_name=query_name).delete()
            logger.info('load data is deleted')
 
            logger.info('Insert new data')
            result = load_date_into_database(products=result, query=query)
            return result
 
        else:
            logger.info('GET data from database')
            result = Result.objects.filter(query=query)
            return result
 
    except ObjectDoesNotExist:
        logger.info('Creating new query and get new data from site')
        result = get_data_from_site(query_name)
        if result == 'Товар не найден':
            raise ProductNotFound('Товар не найден')
        else:
            query = Query.objects.create(query_name=query_name)
            res = load_date_into_database(products=result, query=query)
            return res
  • Вопрос задан
  • 862 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы