Django: django.test TestCase self.assertTemplateUsed
<p>Working on <a href="http://hellowebapp.com" rel="nofollow">Hello Web App</a>.</p>

<p>Please help with TestCase: test_edit_thing.</p>

<p>Here's the error details:</p>

<p>The error in case of '/things/django-book/edit/':</p>

<pre><code># AssertionError: No templates used to render the response
response = self.client.get('/things/django-book/edit/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
</code></pre>

<p>The error in case of '/things/django-book/':</p>

<pre><code># AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
response = self.client.get('/things/django-book/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
</code></pre>

<p>Code Snippet:</p>

<pre><code>from django.contrib.auth.models import AnonymousUser, User
from django.test import TestCase, RequestFactory

from collection.models import Thing
from .views import *

class SimpleTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()
        self.user = User.objects.create_user(username='Foo', password='barbaz')        
        self.thing = Thing.objects.create(name="Django Book",
                                     description="Learn how to build your first Django web app.",
                                     slug="django-book",
                                     user=self.user)

    def test_index(self):
        request = self.factory.get('/index/')
        response = index(request)
        print(response.status_code)
        self.assertEqual(response.status_code, 200)        
        response = self.client.get('/')
        self.assertTemplateUsed(response, 'base.html')

    def test_thing_detail(self):
        django_book = Thing.objects.get(name="Django Book")        
        request = self.factory.get('/things/django-book/')
        response = thing_detail(request, django_book.slug)
        print(response.status_code) 
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/things/django-book/')
        self.assertTemplateUsed(response, 'things/thing_detail.html')

    def test_edit_thing(self):
        django_book = Thing.objects.get(name="Django Book")
        request = self.factory.get('/things/django-book/edit/')
        request.user = django_book.user
        response = edit_thing(request, django_book.slug)
        print(response.status_code) 
        self.assertEqual(response.status_code, 200)

        # AssertionError: No templates used to render the response
        #response = self.client.get('/things/django-book/edit/')

        # AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
        #response = self.client.get('/things/django-book/')
        #self.assertTemplateUsed(response, 'things/edit_thing.html')

        # Right?
        response = self.client.get('/things/django-book/')        
        self.assertTemplateUsed(response, 'things/thing_detail.html')
</code></pre>

<p><a href="https://github.com/hellowebapp/hellowebapp-code/blob/master/collection/views.py" rel="nofollow">views.py</a></p>

<pre><code>from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, redirect
from django.template.defaultfilters import slugify

from collection.forms import ThingForm
from collection.models import Thing


def index(request):
    things = Thing.objects.all()
    return render(request, 'index.html', {
        'things': things,
    })


def thing_detail(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # and pass to the template
    return render(request, 'things/thing_detail.html', {
        'thing': thing,
    })


@login_required
def edit_thing(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # grab the current logged in user and make sure they're the owner of the thing
    if thing.user != request.user:
        raise Http404

    # set the form we're using...
    form_class = ThingForm

    # if we're coming to this view from a submitted form,  
    if request.method == 'POST':
        # grab the data from the submitted form
        form = form_class(data=request.POST, instance=thing)

        if form.is_valid():
            # save the new data
            form.save()
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class(instance=thing)

    # and render the template
    return render(request, 'things/edit_thing.html', {
        'thing': thing,
        'form': form,
    })


def create_thing(request):
    form_class = ThingForm

    # if we're coming from a submitted form, do this
    if request.method == 'POST':
        # grab the data from the submitted form and apply to the form
        form = form_class(request.POST)

        if form.is_valid():
            # create an instance but do not save yet
            thing = form.save(commit=False)

            # set the additional details
            thing.user = request.user
            thing.slug = slugify(thing.name)

            # save the object
            thing.save()

            # redirect to our newly created thing
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class()

    return render(request, 'things/create_thing.html', {
        'form': form,
    })


def browse_by_name(request, initial=None):
    if initial:
        things = Thing.objects.filter(
             name__istartswith=initial).order_by('name')
    else:
        things = Thing.objects.all().order_by('name')

    return render(request, 'search/search.html', {
        'things': things,
        'initial': initial,
    })
</code></pre>

<p>Thanks</p>

<p>So the problem that you was having is that your user wasn't authenticated, and if user is not the same as user of the thing you raise Http404</p>

<p>It in your <code>edit_thing</code> view</p>

<pre><code>if thing.user != request.user:
    raise Http404
</code></pre>

<p>So you needed to be authenticated. And that could be made with <a href="https://docs.djangoproject.com/en/1.10/topics/testing/tools/#django.test.Client.login" rel="nofollow"><code>login</code></a></p>

<pre><code>def test_edit_thing(self):
    django_book = Thing.objects.get(name="Django Book")
    request = self.factory.get('/things/django-book/edit/')
    request.user = django_book.user
    response = edit_thing(request, django_book.slug)
    print(response.status_code)
    self.assertEqual(response.status_code, 200)
    self.client.login(username='Foo', password='barbaz')
    response = self.client.get('/things/django-book/edit/')        
    self.assertTemplateUsed(response, 'things/edit_thing.html')
</code></pre>

python django python-2.7 django-templates django-testing