kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

PPP3: リクエスト/レスポンスのテスト

08-02-03 ユニットテストから環境依存を排除する

リクエスト/レスポンスのテスト

  • テスト時にオブジェクトを入れ替えられるよう、直にクラス名を書かないで指定できるようにしておく

こういうのをDependency Injectionって言うのかな(知らない
一番シンプルな部類だと思うけど

  • 結果をあとで確認できるよう、値をいったんインスタンス変数に保存する

ところでここのサンプルコードは動くのか?
そのままじゃ動かなくてもちょっと足してやれば動きそうな気もする

myview.py

class SomeService():
    pass

def render(*args):
    pass

class MyView:
    someservice_cls = SomeService

    def __init__(self, request):
        self.request = request

    def index(self):
        s = self.someservice_cls()
        result = s.somemethod(**self.request.params)
        self.render_context = dict(result=result)
        return render('index.html', self.render_context)

test_myview.py

import unittest
from myview import MyView

class DummyRequest:
    def __init__(self, params):
        self.params = params

class DummySomeService:
    def somemethod(self, **kwargs):
        return kwargs

class TestIt(unittest.TestCase):
    def test_it(self):
        request = DummyRequest(params={"a": 1})
        target = MyView(request)
        target.someservice_cls = DummySomeService
        result = target.index()
        self.assertEqual(target.render_context["result"], {"a": 1})

どうでしょう

$ pytest test_myview.py
================================================================================== test session starts ===================================================================================
platform linux -- Python 3.6.7, pytest-4.6.2, py-1.8.0, pluggy-0.12.0
rootdir: /home/takahiro/study/PPP3-mac/test
plugins: cov-2.7.1
collected 1 item

test_myview.py .                                                                                                                                                                   [100%]

================================================================================ 1 passed in 0.02 seconds ================================================================================

よさそうだけど
念のため失敗させてみる

$ pytest test_myview.py 
:
test_myview.py F                                                                                                                                                                   [100%]

======================================================================================== FAILURES ========================================================================================
_____________________________________________________________________________________ TestIt.test_it _____________________________________________________________________________________

self = <test_myview.TestIt testMethod=test_it>

    def test_it(self):
        request = DummyRequest(params={"a": 2})
        target = MyView(request)
        target.someservice_cls = DummySomeService
        result = target.index()
>       self.assertEqual(target.render_context["result"], {"a": 1})
E       AssertionError: {'a': 2} != {'a': 1}
E       - {'a': 2}
E       ?       ^
E       
E       + {'a': 1}
E       ?       ^

test_myview.py:21: AssertionError
================================================================================ 1 failed in 0.05 seconds ================================================================================

大丈夫だったみたい