ログイン機能が付いたサービスを Django で初めて作っています。
今、urls.py
に書いたそれぞれの path が login_requred
つきのメソッド or 関数に到達するかどうかのテストを書いているのですが、ログイン状態ではどう判定すればいいのか迷っています。
クラスベースのメソッドに対しては、view.func.view_class
で判定すると意図通りに動いていますが、関数に対してはウェブで多く見られるview.func
で判定するとなぜか関数のアドレス不一致によってFAILEDとなってしまいます。
self.assertEqual(view.func, ajax_respond) AssertionError: <function ajax_respond at 0x10b3351f0> != <function ajax_respond at 0x10af44280>
到達先の関数をlogin_required()でラップしただけなのに、なぜその関数の配置が変わるのが理解できないのですが、しかたないので、関数の判定に関しては関数オブジェクトではなく、関数名で判定するようにしてみました。
まとめると現状では下表のようにしているのですが、なにかもっと良い方法がありましたらお教えいただけますと助かります。
到達先 | assert | 判定結果 |
---|---|---|
クラスベースViewのメソッド | self.assertEqual(view.func.view_class, DrillTopView) | OK |
関数(最初の実装) | self.assertEqual(view.func, ajax_respond) | FAILED |
関数(改善した実装) | self.assertEqual(view.func.__name__, ajax_respond.__name__) | OK |
よろしくお願いいたします。
テスト結果
(venv)$ ./manage.py test /Users/u/tmp/proj Creating test database for alias 'default'... System check identified no issues (0 silenced). F..... ====================================================================== FAIL: test_ajaxレスポンダに飛べるか (main.tests.test_urls.TestUrls) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/u/tmp/proj/mysite/main/tests/test_urls.py", line 62, in test_ajaxレスポンダに飛べるか self.assertEqual(view.func, ajax_respond) AssertionError: <function ajax_respond at 0x10667d280> != <function ajax_respond at 0x1062931f0> ---------------------------------------------------------------------- Ran 6 tests in 2.307s FAILED (failures=1) Destroying test database for alias 'default'...
main/test_urls.py (抜粋)
Python
1from django.test import TestCase, Client 2from django.urls import reverse, resolve 3from django.contrib import auth 4from main.views import (ajax_respond, # snip 5 HomeView, # snip 6 ) 7from users.models import CustomUser 8 9from pprint import pprint 10 11class TestUrls(TestCase): 12 def setUp(self): 13 self.user = CustomUser.objects.create(username='tester', email='tester@example.com', password='pass') 14 self.user.set_password('pass') 15 self.user.save() 16 self.client = Client() 17 self.logged_in = self.client.login(username='tester', password='pass') 18 19 def test_ホーム指定でhomeページに飛べるか(self): 20 self.assertTrue(self.logged_in) 21 self.assertTrue(auth.get_user(self.client).is_authenticated) 22 23 url = '/home/' 24 view = resolve(url) 25 self.assertEqual(view.func.view_class, HomeView) 26 27 # snip 28 29 def test_ajaxレスポンダに飛べるか(self): 30 self.assertTrue(self.logged_in) 31 self.assertTrue(auth.get_user(self.client).is_authenticated) 32 33 url = '/1/ajax/' 34 view = resolve(url) 35 self.assertEqual(view.func.__name__, ajax_respond.__name__) # OK 36 self.assertEqual(view.func, ajax_respond) # FAILED 37 # => AssertionError: <function ajax_respond at 0x10b3351f0> != <function ajax_respond at 0x10af44280>
main/urls.py (抜粋)
python
1from django.urls import path 2from django.contrib.auth.decorators import login_required 3from .views import (ajax_respond, # snip 4 HomeView, # snip 5) 6 7app_name = 'main' 8 9urlpatterns = [ 10 # path('test/', test, name='test'), 11 path('home/', HomeView.as_view(), name='home'), 12 # snip 13 path('<int:pk>/ajax/', login_required(ajax_respond), name='ajax'), 14 # snip 15]
環境(ローカルでテスト中)
- Django 3.2
- Python 3.9
- MacOS Big Sur 11.6.2
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。