Skip to content

Commit 45e3c99

Browse files
author
yangxg
committed
Step30: unittest for comment app
1 parent 5434c22 commit 45e3c99

File tree

8 files changed

+166
-3
lines changed

8 files changed

+166
-3
lines changed

.idea/HelloDjango-blog-tutorial.iml

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ tutorial 分支为项目的主分支,每一篇教程的代码都和历史提
150150
27. [Django 博客实现简单的全文搜索](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/85/)
151151
28. [Django Haystack 全文检索与关键词高亮](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/86/)
152152
29. [单元测试:测试 blog 应用](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/87/)
153+
30. [单元测试:测试评论应用](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/88/)
153154

154155
## 公众号
155156
<p align="center">

comments/tests.py

-3
This file was deleted.

comments/tests/__init__.py

Whitespace-only changes.

comments/tests/base.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from django.apps import apps
2+
from django.contrib.auth.models import User
3+
from django.test import TestCase
4+
5+
from blog.models import Category, Post
6+
7+
8+
class CommentDataTestCase(TestCase):
9+
def setUp(self):
10+
apps.get_app_config("haystack").signal_processor.teardown()
11+
self.user = User.objects.create_superuser(
12+
username="admin", email="[email protected]", password="admin"
13+
)
14+
self.cate = Category.objects.create(name="测试")
15+
self.post = Post.objects.create(
16+
title="测试标题", body="测试内容", category=self.cate, author=self.user,
17+
)

comments/tests/test_models.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from .base import CommentDataTestCase
2+
from ..models import Comment
3+
4+
5+
class CommentModelTestCase(CommentDataTestCase):
6+
def setUp(self) -> None:
7+
super().setUp()
8+
self.comment = Comment.objects.create(
9+
name="评论者", email="[email protected]", text="评论内容", post=self.post,
10+
)
11+
12+
def test_str_representation(self):
13+
self.assertEqual(self.comment.__str__(), "评论者: 评论内容")

comments/tests/test_templatetags.py

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
from datetime import timedelta
2+
3+
from django.apps import apps
4+
from django.contrib.auth.models import User
5+
from django.template import Context, Template
6+
from django.utils import timezone
7+
8+
from blog.models import Category, Post
9+
from .base import CommentDataTestCase
10+
from ..forms import CommentForm
11+
from ..models import Comment
12+
from ..templatetags.comments_extras import show_comment_form, show_comments
13+
14+
15+
class CommentExtraTestCase(CommentDataTestCase):
16+
def setUp(self) -> None:
17+
super().setUp()
18+
self.ctx = Context()
19+
20+
def test_show_comment_form_with_empty_form(self):
21+
template = Template("{% load comments_extras %}" "{% show_comment_form post %}")
22+
form = CommentForm()
23+
context = Context(show_comment_form(self.ctx, self.post))
24+
expected_html = template.render(context)
25+
for field in form:
26+
label = '<label for="{}">{}:</label>'.format(
27+
field.id_for_label, field.label
28+
)
29+
self.assertInHTML(label, expected_html)
30+
self.assertInHTML(str(field), expected_html)
31+
32+
def test_show_comment_form_with_invalid_bound_form(self):
33+
template = Template(
34+
"{% load comments_extras %}" "{% show_comment_form post form %}"
35+
)
36+
invalid_data = {
37+
"email": "invalid_email",
38+
}
39+
form = CommentForm(data=invalid_data)
40+
self.assertFalse(form.is_valid())
41+
context = Context(show_comment_form(self.ctx, self.post, form=form))
42+
expected_html = template.render(context)
43+
for field in form:
44+
label = '<label for="{}">{}:</label>'.format(
45+
field.id_for_label, field.label
46+
)
47+
self.assertInHTML(label, expected_html)
48+
self.assertInHTML(str(field), expected_html)
49+
self.assertInHTML(str(field.errors), expected_html)
50+
51+
def test_show_comments_without_any_comment(self):
52+
template = Template("{% load comments_extras %}" "{% show_comments post %}")
53+
ctx_dict = show_comments(self.ctx, self.post)
54+
ctx_dict["post"] = self.post
55+
context = Context(ctx_dict)
56+
expected_html = template.render(context)
57+
self.assertInHTML("<h3>评论列表,共 <span>0</span> 条评论</h3>", expected_html)
58+
self.assertInHTML("暂无评论", expected_html)
59+
60+
def test_show_comments_with_comments(self):
61+
comment1 = Comment.objects.create(
62+
name="评论者1", email="[email protected]", text="评论内容1", post=self.post,
63+
)
64+
comment2 = Comment.objects.create(
65+
name="评论者2",
66+
67+
text="评论内容2",
68+
post=self.post,
69+
created_time=timezone.now() - timedelta(days=1),
70+
)
71+
template = Template("{% load comments_extras %}" "{% show_comments post %}")
72+
ctx_dict = show_comments(self.ctx, self.post)
73+
ctx_dict["post"] = self.post
74+
context = Context(ctx_dict)
75+
expected_html = template.render(context)
76+
self.assertInHTML("<h3>评论列表,共 <span>2</span> 条评论</h3>", expected_html)
77+
self.assertInHTML(comment1.name, expected_html)
78+
self.assertInHTML(comment1.text, expected_html)
79+
self.assertInHTML(comment2.name, expected_html)
80+
self.assertInHTML(comment2.text, expected_html)
81+
self.assertQuerysetEqual(
82+
ctx_dict["comment_list"], [repr(c) for c in [comment1, comment2]]
83+
)

comments/tests/test_views.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from django.apps import apps
2+
from django.contrib.auth.models import User
3+
from django.urls import reverse
4+
5+
from blog.models import Category, Post
6+
7+
from ..models import Comment
8+
from .base import CommentDataTestCase
9+
10+
11+
class CommentViewTestCase(CommentDataTestCase):
12+
def setUp(self) -> None:
13+
super().setUp()
14+
self.url = reverse("comments:comment", kwargs={"post_pk": self.post.pk})
15+
16+
def test_comment_a_nonexistent_post(self):
17+
url = reverse("comments:comment", kwargs={"post_pk": 100})
18+
response = self.client.post(url, {})
19+
self.assertEqual(response.status_code, 404)
20+
21+
def test_invalid_comment_data(self):
22+
invalid_data = {
23+
"email": "invalid_email",
24+
}
25+
response = self.client.post(self.url, invalid_data)
26+
self.assertTemplateUsed(response, "comments/preview.html")
27+
self.assertIn("post", response.context)
28+
self.assertIn("form", response.context)
29+
form = response.context["form"]
30+
for field_name, errors in form.errors.items():
31+
for err in errors:
32+
self.assertContains(response, err)
33+
self.assertContains(response, "评论发表失败!请修改表单中的错误后重新提交。")
34+
35+
def test_valid_comment_data(self):
36+
valid_data = {
37+
"name": "评论者",
38+
"email": "[email protected]",
39+
"text": "评论内容",
40+
}
41+
response = self.client.post(self.url, valid_data, follow=True)
42+
self.assertRedirects(response, self.post.get_absolute_url())
43+
self.assertContains(response, "评论发表成功!")
44+
self.assertEqual(Comment.objects.count(), 1)
45+
comment = Comment.objects.first()
46+
self.assertEqual(comment.name, valid_data["name"])
47+
self.assertEqual(comment.text, valid_data["text"])

0 commit comments

Comments
 (0)