【问题标题】:How can I unit tests for this Django Form我怎样才能对这个 Django 表单进行单元测试
【发布时间】:2023-02-11 14:47:22
【问题描述】:

我做了覆盖率报告,有很多地方没有覆盖,你知道我该如何编写测试吗?

视图.py没有被掩盖

def addreview(request, u_id, shop_id):
    url = request.META.get('HTTP_REFERER')
    shop = shop_detail.objects.get(id=shop_id)
    user = Profile.objects.get(customer=u_id)
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            data = Review()
            data.review_text = form.cleaned_data['review_text']
            data.review_rating = form.cleaned_data['review_rating']
            data.shop = shop
            data.user = user
            data.save()
            return redirect(url)


def rating(request):
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse('customer_login'))
    if request.method == 'POST':
        form = RateUsForm(request.POST)
        if form.is_valid():
            rate = RateUs()
            rate.rate_text = form.cleaned_data['rate_text']
            rate.rating = form.cleaned_data['rating']
            rate.user = request.user
            rate.save()
            return HttpResponseRedirect(reverse("index"))
    return render(request, 'shop/rate.html')

模型.py

class Review(models.Model):
    user = models.ForeignKey(Profile,on_delete=models.CASCADE)
    shop = models.ForeignKey(shop_detail,on_delete=models.CASCADE)
    review_text = models.TextField(max_length=300)
    review_rating = models.IntegerField()

    def __str__(self):
        return f"{self.review_rating}"


class RateUs(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    rate_text = models.TextField()
    rating = models.IntegerField()

    def __str__(self):
        return f"{self.rating}"

表单.py

class ReviewForm(forms.ModelForm):
    class Meta:
        model= Review
        fields= ["review_text", "review_rating"]

class RateUsForm(forms.ModelForm):
    class Meta:
        model= RateUs
        fields= ["rate_text","rating"]

这就是我写的评分

def test_valid_rating(self):
        rateus1 = RateUs.objects.first()
        data={
            "user": rateus1.user,
            "rate_text": rateus1.rate_text,
            "rating": rateus1.rating
        }
        response = self.client.post(reverse('rating'), data=data)
        self.assertEqual(response.status_code, 302)

当我尝试编写测试时添加评论我得到了 customer.models.Profile.DoesNotExist:配置文件匹配查询不存在。

【问题讨论】:

    标签: django unit-testing testing django-testing django-tests


    【解决方案1】:

    以下是您需要实现的内容才能获得测试功能的方法:

    # Imports needed
    import pytest
    from unittest.mock import MagicMock, patch
    
    def test_addreview(self):
        # Here probably you will need to create a User before.
        user = User.objects.create(username='testuser', id=15445)
        shop = shop_detail.objects.create(id=19889)
        Profile.objects.create(customer=user.pk)
        mock_request = MagicMock(
            POST={'review_text': 'test', 'review_rating': 5},
            META={'HTTP_REFERER': 'http://testserver/'},
            method='POST',
        )
        self.assert(Review.objects.count(), 0)
        with patch('django.shortcuts.redirect') as redirect_mock:
            addreview(mock_request, user.pk, shop.pk)
        redirect_mock.assert_called_with('http://testserver/')
        self.assert(Review.objects.count(), 1)
    
    
    def test_addreview_not_redirected(self):
        # Here probably you will need to create a User before.
        user = User.objects.create(username='testuser', id=15445)
        shop = shop_detail.objects.create(id=19889)
        Profile.objects.create(customer=user.pk)
        mock_request = MagicMock(
            POST={'review_text': 'test', 'review_rating': 5},
            META={'HTTP_REFERER': 'http://testserver/'},
            method='GET',
        )
        self.assert(Review.objects.count(), 0)
        with patch('django.shortcuts.redirect') as redirect_mock:
            addreview(mock_request, user.pk, shop.pk)
        redirect_mock.assert_not_called()
        self.assert(Review.objects.count(), 0)
    
    def test_addreview_raise_exception_profile_not_found(self):
        # Here probably you will need to create a User before.
        user = User.objects.create(username='testuser', id=15445)
        shop = shop_detail.objects.create(id=19889)
        mock_request = MagicMock(
            POST={'review_text': 'test', 'review_rating': 5},
            META={'HTTP_REFERER': 'http://testserver/'},
            method='GET',
        )
        self.assert(Review.objects.count(), 0)
        self.assert(Profile.objects.count(), 0)
        with pytest.raises(Profile.DoesNotExist):
            addreview(mock_request, user.pk, shop.pk)
        self.assert(Review.objects.count(), 0)
        self.assert(Profile.objects.count(), 0)
    

    可能您需要对每个示例进行一些调整,因为它只是您必须如何实施它的指南。

    • 使用此类测试时,如果您希望存在 Profile 等,您需要先创建它,以预测调用该函数后将执行的代码行。
    • Mock 在这种情况下非常重要,我们模拟 request 并模拟 request 具有的所有属性。
    • 我们也模拟redirect,但在这种情况下只是为了知道它是否被调用。
    • 最后我们生成了一个案例,我们期望代码在调用函数时生成异常。
    • 通常要在测试中创建模型对象,最佳做法是使用https://factoryboy.readthedocs.io/en/stable/ 看一看。

    【讨论】:

      猜你喜欢
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 2022-11-28
      • 2020-10-10
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多