2012-05-10 8 views
10

これまでに単体テストを行ったことはありません。私はそれを習得したい。webapp2リクエストハンドラからjinja2テンプレートに渡されたテンプレート変数をunittestする方法

webapp2ハンドラをテストしようとしています。これを行うには、私はハンドラなどにリクエストを送信するために良いアイデアだと思った:

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

問題があり、レスポンスは主にHTMLのちょうど束であるなど

私が見てみたいですハンドラからHTMLに変換される前に私のjinja2テンプレートに渡されたもので。

私のテストは、ハンドラクラスコード内の状態で取得します。私は特定の変数が応答ハンドラでどのように見えるかを見ることができないようにしてから、レンダリングのテンプレートがrender_to_response()に渡される前にどのように見えるようにしたいのですか?

これらの変数をテストしたい正しい値。

これまでのテストコードですが、レスポンス= request.get_response()は生の変数ではなくhtmlの束を私に与えてくれるので固執しています。

import unittest 
#from google.appengine.ext import db 
#from google.appengine.ext import testbed 
#from google.appengine.datastore import datastore_stub_util 
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() 

、ここでは私のハンドラである:

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("-->","") 

     for fn in file_names: 
      with open('blog_posts/%s' % fn) as file_: 
       heading = get_line(file_) 
       link_name = get_line(file_) 
       category = get_line(file_) 

      date_ = datetime.strptime(fn.split("_")[0], "%Y%m%d") 

      blog_dict = {'date': date_, 'heading': heading, 
         'link_name': link_name, 
         'category': category, 
         'filename': fn.replace(".html", ""), 
         'raw_file_name': fn} 

      blogs.append(blog_dict) 

     categories = Counter(d['category'] for d in blogs) 
     templates = {'categories': categories, 
        'blogs': blogs, 
        'file_name_filter': file_name_filter, 
        'category_filter': category_filter} 

     assert(len(file_names) == len(set(d['link_name'] for d in blogs))) 

     self.render_template('home.html', **templates) 

とここに私たBaseHandlerです:私は、おそらく

class BaseHandler(webapp2.RequestHandler): 
    @webapp2.cached_property 
    def jinja2(self): 
     return jinja2.get_jinja2(app=self.app) 

    def render_template(self, filename, **kwargs): 
     #kwargs.update({}) 
     #TODO() datastore caching here for caching of (handlername, handler parameters, changeable parameters, app_upload_date) 
     #TODO() write rendered page to its own html file, and just serve that whole file. (includes all posts). JQuery can show/hide posts. 
     self.response.write(self.jinja2.render_template(filename, **kwargs)) 

はおそらく、私はユニットテストを行う方法の間違った考えを持っている、または私のコードをテストしやすくする方法で書かれていたはずですか?または私のコードの状態を取得するいくつかの方法はありますか?誰かが、その後、テストが壊れるコードを再作成し、変数名を変更した場合にも

..

私の状況にアドバイスしてください:X

答えて

6

あなたがBaseHandler.render_template方法を模擬し、テストすることができ、そのパラメーター。

一般的なPythonモッキングフレームワークのリストについては、this questionを参照してください。

5

proppyの提案のおかげで私はモックを使い終わった。

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

(モックはPython 3の一部またはunittest.mockとして含まれています)

だからここに私はwebapp2を中に持っているものに似ている私のmain.pyコードです:

代わりにBaseHandler.render_templateの

ノート私が持っている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" 

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() 

このコードが出力の多くを提供し、ここでのサンプルです:

44444 
in TheHandler's get() 
last_sup 
TheHandler's return string 
in TheHandler's get() 
last_sup 
TheHandler's return string 
--- 
True 
[call(42), call(123)] 
555555 
関連する問題