测试 Django 视图
Testing Django view
我正在尝试测试以下视图
def generate_exercise_edl(request, ex_pk, unit_pk, *args, **kwargs):
ex_instance = Exercises.objects.get(id=ex_pk)
unit_instance = Units.objects.get(id=unit_pk)
unit_edl = UnitEdl.objects.filter(unit=unit_instance)
locations = Locations.objects.all()
unit_edl = list(unit_edl)
print(request)
print(request.POST)
print(request.user)
if request.method == "POST":
for item in unit_edl:
ExerciseEdl.objects.update_or_create(unit=unit_instance, exercise=ex_instance, equipment=item.equipment,
quantity=item.quantity, location=Locations.objects.get(location="Okinawa"))
print(request)
return redirect('exercise-equipment', ex_pk=ex_pk, unit_pk=unit_pk)
else:
messages.error(
request, f'Failed to add/update the {unit_instance.unit_name} edl for {ex_instance.exercise}.')
context = {
'ex_instance': ex_instance,
'unit_instance': unit_instance,
'unit_edl': unit_edl,
'locations': locations,
}
return render(request, 'exercise/exercise_edl.html', context)
这是我的测试代码
def test_generate_edl(self):
unit_edl = UnitEdl.objects.filter(unit=unit.pk)
for edl in unit_edl:
ExerciseEdl.objects.update_or_create(
unit=unit,
exercise=ex,
equipment=edl.equipment,
quantity=edl.quantity,
location=loc
)
response = self.client.post(
f'/exercise/{ex.pk}/edl/{unit.pk}/convert/')
ex_edl = ExerciseEdl.objects.all().count()
self.assertEquals(ex_edl, 2)
self.assertEqual(response.status_code, 302)
这是视图URL
path('exercise/<int:ex_pk>/edl/<int:unit_pk>/convert', views.generate_exercise_edl, name='generate-edl'),
以及调用我函数的模板部分
<form action="{% url 'generate-edl' ex_pk=ex_instance.id unit_pk=unit_instance.id %}" method="post">
{% csrf_token %}
<input class="btn btn-primary btn-sm mt-2" type="submit" value="Generate EDL">
</form>
我的测试 returns 404,不是 302,但是站点上的功能有效,并重定向了您。
f'/exercise/{ex.pk}/edl/{unit.pk}/convert/' 没有映射到任何模板,它只是函数的 url。过去,当我错误地写入 post 数据时,我的测试返回了状态码 404。
打印(request.POST) returns:
<QueryDict: {'csrfmiddlewaretoken':
['ZYT0dgMZqqgmCo2OufdI9B0hIJ5k5qPKcxnkReWPZy0iY9McaBO7MHENjYLzH66O']}>
这是有道理的,因为我没有发送任何 post 数据,只是 csrf 令牌。
我想知道的是,我使用'response = self.client.post(
f'/练习/{ex.pk}/edl/{unit.pk}/convert/')'?
在我的其他测试中,我将 post 数据与 URL 一起包含在字典中,但是这个函数不使用任何数据,所以我只是 运行 一个类似的函数。
有没有更好的方法来测试这个?我应该重构吗?
您需要使用 reverse
构建您的 URL 而不是硬编码。由于您对其进行了硬编码,因此它得到了 404,因为 URL 测试试图 post 是不正确的。
我不知道您的 URLs 文件中的 app_name
,您需要将其添加到反面。例如,如果它是 excercise
它将是 exercise:generate-edl
.
from django.urls import reverse
response = self.client.post(reverse(
'<app_name>:generate-edl',
kwargs={
ex_pk: ex.pk,
unit_pk: unit.pk,
}
))
我正在尝试测试以下视图
def generate_exercise_edl(request, ex_pk, unit_pk, *args, **kwargs):
ex_instance = Exercises.objects.get(id=ex_pk)
unit_instance = Units.objects.get(id=unit_pk)
unit_edl = UnitEdl.objects.filter(unit=unit_instance)
locations = Locations.objects.all()
unit_edl = list(unit_edl)
print(request)
print(request.POST)
print(request.user)
if request.method == "POST":
for item in unit_edl:
ExerciseEdl.objects.update_or_create(unit=unit_instance, exercise=ex_instance, equipment=item.equipment,
quantity=item.quantity, location=Locations.objects.get(location="Okinawa"))
print(request)
return redirect('exercise-equipment', ex_pk=ex_pk, unit_pk=unit_pk)
else:
messages.error(
request, f'Failed to add/update the {unit_instance.unit_name} edl for {ex_instance.exercise}.')
context = {
'ex_instance': ex_instance,
'unit_instance': unit_instance,
'unit_edl': unit_edl,
'locations': locations,
}
return render(request, 'exercise/exercise_edl.html', context)
这是我的测试代码
def test_generate_edl(self):
unit_edl = UnitEdl.objects.filter(unit=unit.pk)
for edl in unit_edl:
ExerciseEdl.objects.update_or_create(
unit=unit,
exercise=ex,
equipment=edl.equipment,
quantity=edl.quantity,
location=loc
)
response = self.client.post(
f'/exercise/{ex.pk}/edl/{unit.pk}/convert/')
ex_edl = ExerciseEdl.objects.all().count()
self.assertEquals(ex_edl, 2)
self.assertEqual(response.status_code, 302)
这是视图URL
path('exercise/<int:ex_pk>/edl/<int:unit_pk>/convert', views.generate_exercise_edl, name='generate-edl'),
以及调用我函数的模板部分
<form action="{% url 'generate-edl' ex_pk=ex_instance.id unit_pk=unit_instance.id %}" method="post">
{% csrf_token %}
<input class="btn btn-primary btn-sm mt-2" type="submit" value="Generate EDL">
</form>
我的测试 returns 404,不是 302,但是站点上的功能有效,并重定向了您。 f'/exercise/{ex.pk}/edl/{unit.pk}/convert/' 没有映射到任何模板,它只是函数的 url。过去,当我错误地写入 post 数据时,我的测试返回了状态码 404。
打印(request.POST) returns:
<QueryDict: {'csrfmiddlewaretoken': ['ZYT0dgMZqqgmCo2OufdI9B0hIJ5k5qPKcxnkReWPZy0iY9McaBO7MHENjYLzH66O']}>
这是有道理的,因为我没有发送任何 post 数据,只是 csrf 令牌。
我想知道的是,我使用'response = self.client.post( f'/练习/{ex.pk}/edl/{unit.pk}/convert/')'? 在我的其他测试中,我将 post 数据与 URL 一起包含在字典中,但是这个函数不使用任何数据,所以我只是 运行 一个类似的函数。
有没有更好的方法来测试这个?我应该重构吗?
您需要使用 reverse
构建您的 URL 而不是硬编码。由于您对其进行了硬编码,因此它得到了 404,因为 URL 测试试图 post 是不正确的。
我不知道您的 URLs 文件中的 app_name
,您需要将其添加到反面。例如,如果它是 excercise
它将是 exercise:generate-edl
.
from django.urls import reverse
response = self.client.post(reverse(
'<app_name>:generate-edl',
kwargs={
ex_pk: ex.pk,
unit_pk: unit.pk,
}
))