Alex Rivera | Logout

how to unittest the template variables passed to jinja2 template from webapp2 request handler

Asked 2012-05-10T03:34:32.100
10

I'm trying to test my webapp2 handlers. To do this, I thought it would be a good idea to send a request to the handler e.g.:

request = webapp2.Request.blank('/')
# Get a response for that request.
response = request.get_response(main.app)

The problem is, response is mostly just a bunch of HTML etc.

I want to look at what was passed to my jinja2 template from the handler before it was turned into HTML.

I want my test to get at the state within the handler class code. I wan't to be able to see what certain variables looked like in the response handler, and then I want to see what the dict templates looks like before it was passed to render_to_response()

I want to test these variables have the correct values.

Here is my test code so far, but I'm stuck because response = request.get_response() just gives me a bunch of html and not the raw variables.

import unittest
import main
import webapp2

class DemoTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def testNothing(self):
        self.assertEqual(42, 21 + 21)

    def testHomeHandler(self):
        # Build a request object passing the URI path to be tested.
        # You can also pass headers, query arguments etc.
        request = webapp2.Request.blank('/')
        # Get a response for that request.
        response = request.get_response(main.app)

        # Let's check if the response is correct.
        self.assertEqual(response.status_int, 200)
        self.assertEqual(response.body, 'Hello, world!')


if __name__ == '__main__':
    unittest.main()

and here is my handler:

class HomeHandler(BaseHandler):
    def get(self, file_name_filter=None, category_filter=None):
        file_names = os.listdir('blog_posts')
        blogs = []

        get_line = lambda file_: file_.readline().strip().replace("<!--","").replace("-->&
Edit
Report

1 Answer

5

Thanks to proppy's suggestion I ended up using a mock.

http://www.voidspace.org.uk/python/mock/

(mock is included as part or unittest.mock in python 3)

So here is my main.py code which is similar to what I have in webapp2:

note instead of BaseHandler.render_template i have BaseHandler.say_yo

__author__ = 'Robert'

print "hello from main"

class BaseHandler():
    def say_yo(self,some_number=99):
        print "yo"
        return "sup"

class TheHandler(BaseHandler):
    def get(self, my_number=42):
        print "in TheHandler's get()"
        print self.say_yo(my_number)
        return "TheHandler's return string"

and atest.py:

__author__ = 'Robert'

import unittest
import main
from mock import patch

class DemoTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def testNothing(self):
        self.assertEqual(42, 21 + 21)

    def testSomeRequests(self):
        print "hi"
        bh = main.BaseHandler()
        print bh.say_yo()

        print "1111111"

        with patch('main.BaseHandler.say_yo') as patched_bh:
            print dir(patched_bh)
            patched_bh.return_value = 'double_sup'
            bh2 = main.BaseHandler()
            print bh2.say_yo()
            print "222222"

        bh3 = main.BaseHandler()
        print bh3.say_yo()

        print "3333"

        th = main.TheHandler()
        print th.get()

        print "44444"
        with patch('main.BaseHandler.say_yo') as patched_bh:
            patched_bh.return_value = 'last_sup'
            th = main.TheHandler()
            print th.get()
            print th.get(123)
            print "---"
            print patched_bh.called
            print patched_bh.call_args_list
            print "555555"



if __name__ == '__main__':
    unittest.main()
answered 2012-05-11T05:39:10.053

Your Answer