如何在使用django.test TestCase

时间:2016-08-12 15:10:50

标签: python django unit-testing templates views

我正在尝试访问将要发送到模板的对象'wine'。基本上,在这个例子中,我有通过瓶子,玻璃或两者出售的葡萄酒。我进行的第一次测试应该能够检索发送到模板的“葡萄酒”对象中的所有3种葡萄酒。 (create_wine()是一个自定义的Wine.objects.create()方法)。

如果你注意到,我正在使用django.test导入TestCase,所以我有一个self.client对象可供使用。另外,如果您注意到,我正在向您展示我在'(调试)'文本中尝试去顶的位置。

我真正想要的是预呈现的json。在我看来,视图使用对象呈现html来创建它需要的html并返回它。那么如何访问这个预渲染对象?

问题是我将使用相同的视图来渲染这些葡萄酒对象。如果可能的话,我想使用相同的模板,这意味着将数据发送到视图并重写它,以便在渲染之前抓取正确的葡萄酒。我觉得这没关系。如果这打破了django方法论,我全都听见了。

还有其他方法可以解决这个问题,还是我非常接近?

代码

视图

def wine_list(request):
    wines = Wine.objects.filter(is_active=True)
    return render(request, 'wine/wine_list.html', {'wines': wines})

网址

urlpatterns = [
    url(r'^$', 'wine.views.wine_list', name='wine_list'),
    url(r'^bottle/$', 'wine.views.wine_list', name='wine_list_bottle'),
    url(r'^glass/$', 'wine.views.wine_list', name='wine_list_glass'),
    url(r'^([0-9]+)/$', 'wine.views.wine_details', name='wine_detail'),
]

UT

    from django.test import TestCase

    def test_both_wine_glass_and_bottle_pull_different_objects(self):

        # Todo: how to pull object info from view
        self.create_wine(container="bottle")
        self.create_wine(container="glass")
        self.create_wine(container="both")

        request = self.client.get("/wine/")
        from wine.views import wine_list
        result = wine_list(request)
(debug) result

        # assert wine/ wine is both glass and bottle
        # assert wine/glass/ wine is only both or glass wines
        # assert wine/bottle/ wine is only both or bottle wines
        self.fail("finish the test")

'结果'在(调试)

result = {HttpResponse} <HttpResponse status_code=200, "text/html; charset=utf-8">
 _charset = {NoneType} None
 _closable_objects = {list} <class 'list'>: []
 _container = {list} <class 'list'>: [b'<!DOCTYPE html>\n<html lang="en">\n<head>\n    <meta charset="UTF-8">\n    <title>Wine List</title>\n    \n    <link rel="stylesheet" href="/static/wine/reset.css">\n    <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<bod
 _handler_class = {NoneType} None
 _headers = {dict} {'content-type': ('Content-Type', 'text/html; charset=utf-8')}
 _reason_phrase = {NoneType} None
 charset = {str} 'utf-8'
 closed = {bool} False
 content = {bytes} b'<!DOCTYPE html>\n<html lang="en">\n<head>\n    <meta charset="UTF-8">\n    <title>Wine List</title>\n    \n    <link rel="stylesheet" href="/static/wine/reset.css">\n    <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<body>\n    <header c
 cookies = {SimpleCookie} 
 reason_phrase = {str} 'OK'
 status_code = {int} 200
 streaming = {bool} False

其他通过单元测试(如果这些有帮助的话)

    self.create_wine(container="both")

    bottle = Wine.bottle.all()
    glass = Wine.glass.all()
    both = Wine.objects.all()

    self.assertEqual(2, len(bottle))
    self.assertEqual(2, len(glass))
    self.assertEqual(3, len(both))

def test_both_wine_glass_and_bottle_pull_the_same_template(self):
    bottle_list = self.client.get('/wine/bottle/')
    glass_list = self.client.get('/wine/glass/')
    both_list = self.client.get('/wine/')

    self.assertTemplateUsed(both_list, 'wine/wine_list.html')
    self.assertTemplateUsed(bottle_list, 'wine/wine_list.html')
    self.assertTemplateUsed(glass_list, 'wine/wine_list.html')

简单模板wine_list.html

{% extends 'wine/base.html' %}
{% block content %}
    <section id="wine_content">
        <div class="cards">

            {% for wine in wines %}
            <div class="card">
                <a href="/wine/{{ wine.id }}">
                    <h4>{{ wine.name }}</h4>
                    <p>{{ wine.vintage }}</p>
                    <p>{{ wine.description}}</p>
                </a>
            </div>
            {% endfor %}

        </div>
    </section>

{% endblock %}

1 个答案:

答案 0 :(得分:2)

您误解了测试客户端的工作原理。当您致电self.client.get("/wine/")时,它会模拟对/wine/的请求,并调用您的wine_list视图。您不必手动拨打wine_list

client.get()调用会返回响应。然后,您可以使用响应进行测试断言,并从response.context获取项目。

    response = self.client.get("/wine/")
    self.assertEqual(response.status_code, 200)  # check 200 OK response
    wines = response.context['wines']  # this is the list of wines you included in the context
    # check that wines is as you expected.
    for wine in wines:
        # All wines should be active
        self.assertTrue(wine.is_active)
    ...