ログイン機能が付いたサービスを 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
from django.test import TestCase, Client from django.urls import reverse, resolve from django.contrib import auth from main.views import (ajax_respond, # snip HomeView, # snip ) from users.models import CustomUser from pprint import pprint class TestUrls(TestCase): def setUp(self): self.user = CustomUser.objects.create(username='tester', email='tester@example.com', password='pass') self.user.set_password('pass') self.user.save() self.client = Client() self.logged_in = self.client.login(username='tester', password='pass') def test_ホーム指定でhomeページに飛べるか(self): self.assertTrue(self.logged_in) self.assertTrue(auth.get_user(self.client).is_authenticated) url = '/home/' view = resolve(url) self.assertEqual(view.func.view_class, HomeView) # snip def test_ajaxレスポンダに飛べるか(self): self.assertTrue(self.logged_in) self.assertTrue(auth.get_user(self.client).is_authenticated) url = '/1/ajax/' view = resolve(url) self.assertEqual(view.func.__name__, ajax_respond.__name__) # OK self.assertEqual(view.func, ajax_respond) # FAILED # => AssertionError: <function ajax_respond at 0x10b3351f0> != <function ajax_respond at 0x10af44280>
main/urls.py (抜粋)
python
from django.urls import path from django.contrib.auth.decorators import login_required from .views import (ajax_respond, # snip HomeView, # snip ) app_name = 'main' urlpatterns = [ # path('test/', test, name='test'), path('home/', HomeView.as_view(), name='home'), # snip path('<int:pk>/ajax/', login_required(ajax_respond), name='ajax'), # snip ]
環境(ローカルでテスト中)
- Django 3.2
- Python 3.9
- MacOS Big Sur 11.6.2
まだ回答がついていません
会員登録して回答してみよう