【发布时间】:2011-06-21 00:04:39
【问题描述】:
我正在做一些测试,我对URLResolver 还不是很熟悉,但我想快速解决这个问题。
在TestCase 中,我想向解析器添加一个URL,这样我就可以使用Client.get('/url/') 并将其与urls.py 分开。
【问题讨论】:
标签: django unit-testing url testcase
我正在做一些测试,我对URLResolver 还不是很熟悉,但我想快速解决这个问题。
在TestCase 中,我想向解析器添加一个URL,这样我就可以使用Client.get('/url/') 并将其与urls.py 分开。
【问题讨论】:
标签: django unit-testing url testcase
https://docs.djangoproject.com/en/2.1/topics/testing/tools/#urlconf-configuration
在你的测试中:
class TestMyViews(TestCase):
urls = 'myapp.test_urls'
这将使用myapp/test_urls.py 作为ROOT_URLCONF。
【讨论】:
我知道这是不久前提出的问题,但我想我会再次回答它以提供更完整和最新的内容。
您有两种选择来解决这个问题,一种是提供您自己的 urls 文件,正如 SystemParadox 的回答所建议的那样:
class MyTestCase(TestCase):
urls = 'my_app.test_urls'
另一个是修改你的网址。这不是处理覆盖 url 的推荐方法,但您可能会遇到仍然需要它的情况。要在不影响其余测试用例的情况下执行此操作,您应该在 setUp() 方法中执行此操作,然后在您的 tearDown() 方法中进行清理。
import my_app.urls
from django.conf.urls import patterns
class MyTestCase(TestCase):
urls = 'my_app.urls'
def setUp(self):
super(MyTestCase, self).setUp()
self.original_urls = my_app.urls.urlpatterns
my_app.urls.urlpatterns += patterns(
'',
(r'^my/test/url/pattern$', my_view),
)
def tearDown(self):
super(MyTestCase, self).tearDown()
my_app.urls.urlpatterns = self.original_urls
请注意,如果您省略 urls 类属性,这将不起作用。这是因为 URL 将被缓存,如果您将测试与其他测试用例一起运行,您的猴子补丁将不会生效。
【讨论】:
my_app.urls 在这种情况下是默认的应用程序 urls 模块,而不是特定于测试的模块,它是强制重新加载 url 的一种 hacky 方式。我刚刚添加它是因为我遇到了一个案例,猴子修补实际上需要比重新创建整个 urls 模块更费力的代码。
自 Django 1.8 using of django.test.TestCase.urls is deprecated.您可以改用django.test.utils.override_settings:
from django.test import TestCase
from django.test.utils import override_settings
urlpatterns = [
# custom urlconf
]
@override_settings(ROOT_URLCONF=__name__)
class MyTestCase(TestCase):
pass
override_settings 可以应用于整个类或特定方法。
【讨论】:
from myapp.urls import urlpatterns as base_patterns 然后urlpatterns = base_patterns + [<your custom patterns here>]
from myapp.urls import urlpatterns as base_patterns 对我不起作用,因为我对所有其他 URL 的测试都依赖于完整路径。我不得不做my_project.urls import urlpatterns as base_patterns。另外,因为它是my_project.urls,所以我必须在测试中编写完整路径(例如/myapp/path/to/my/view 而不是/path/to/my/view)。
无法使用上述答案运行它。甚至没有override_settings。
找到了一个适合我的解决方案。我的用例是编写一些集成测试,我想在我需要应用程序的 url 的地方测试 put/post 方法。
这里的主要线索是使用django.urls的set_urlconf函数,而不是在类中覆盖它或使用override_settings。
from django.test import TestCase
from django.urls import reverse, set_urlconf
class MyTests(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
set_urlconf('yourapp.urls') # yourapp is the folder where you define your root urlconf.
def test_url_resolving_with_app_urlconf(self):
response = self.client.put(
path=reverse('namespace:to:your:view-name'), data=test_data
)
【讨论】: