【问题标题】:django how to assert url pattern resolves to correct class based view functiondjango 如何断言 url 模式解析为正确的基于类的视图函数
【发布时间】:2015-02-03 21:56:35
【问题描述】:

我有一个基于类的视图

class HomePage(View):
   def get(self, request):
       return HttpResponse('<p>This is content.</p>')

和url-pattern定义如下:

urlpatterns = patterns('',
                  url(r'^$', HomePage.as_view()),
              )

为了这个模式解析为当前视图函数,我写了一个这样的测试:

class HomePageTest(TestCase):

def test_root_url_resolves_to_home_page_view(self):
    found = resolve('/')
    self.assertIsInstance(found.func, HomePage)

通过运行此单元测试,我收到以下错误:

self.assertIsInstance(found.func, HomePage)
AssertionError: <function HomePage at 0x7f85dd2c7840> is not an instance of <class 'web.views.HomePage'>

知道如何测试这个案例吗?

【问题讨论】:

    标签: django django-views python-unittest django-unittest


    【解决方案1】:

    Django 的View.as_view() 创建一个带有view_class 属性的函数,该属性指向基于类的视图。所以使用:

    self.assertEquals(found.func.view_class, HomePage)
    

    避免了不同模块中两个基于类的视图同名的问题。

    【讨论】:

      【解决方案2】:

      可能这是一个老问题,但在 django>=1.8 断言之类的

      self.assertEquals(found.func.func_name, HomePage.__name__)
      

      AttributeError: 'function' object has no attribute 'func_name' 所以我把它改成了

      self.assertEqual(found.func.__name__, HomePage.__name__)
      

      【讨论】:

        【解决方案3】:

        Resolve 将返回调用HomePage.as_view() 时返回的函数,而不是该类型的对象。但是,通过快速测试,您可能有一种方法可以编写此测试:

        self.assertEquals(found.func.func_name, HomePage.__name__)
        

        请注意,这里我们指定 HomePage.__name__ 而不是 'HomePage',因为如果使用重构工具更改了类的名称,这将被拾取。

        这样做的缺点是,如果您连接了一个具有相同名称但来自不同模块的视图类,则此单元测试不会失败。当然,使用诸如HomePage 之类的通用视图类名称的风险更大,但使用其他视图类的风险应该更小。

        【讨论】:

        • 但我想知道我是否可以仅对特定的类实例使用断言。这意味着不使用硬编码的类名。
        • 我知道这并不理想,但不幸的是我不确定如何从resolve返回的函数中获取类对象。如果您想在断言中使用类型对象(以便它处理重构),您可以在断言中使用HomePage.__name__
        • 我已经按照您指定的方式进行了相同的操作,但提出了这个问题以确保 Django 是否提供了更好的方法。谢谢
        【解决方案4】:

        我以另一种方式做到了,因为 Valentjedi 不适合我; 我做到了。:

        class HomePageTest(TestCase):
            def test_root_url_resolves_to_home_page_view(self):
                found = resolve('/')
                self.assertEqual(found.view_name, "home")
        

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2014-01-22
          • 2014-02-16
          • 2021-05-30
          • 1970-01-01
          • 2021-01-24
          • 1970-01-01
          • 2012-12-28
          • 1970-01-01
          • 2021-03-28
          相关资源
          最近更新 更多