如何使用urldispatch自动envoke上下文工厂内部视图测试

2024-06-28 11:41:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个现有的金字塔应用程序,利用url调度。它的URL格式为“/kind1/{id1}/kind2/{id2}…/action”。所以遍历应该是理想的,但它没有被使用。你知道吗

在每个视图中,都有一个从url获取实例的函数调用。例如,可能会有一个类似thingy_instance = get_thingy_from_url(request)的调用

现在我需要向视图添加权限。所以我在路由配置中添加了上下文工厂。类似于:config.add_route('thingy_action','/kind1/{id1}/kind2/{id2}.../action', factory='ThingyContext')

现在ThingyContext获取对象是有意义的,这样在视图本身中我就可以做thingy_instance = request.context.thingy_instance,而不是thingy_instance = get_thingy_from_url(request)

到目前为止,这是相当直接和可行的。但是它破坏了所有直接测试视图的单元测试,因为没有填充请求上下文。你知道吗

例如,这样的测试:

def test_thingy_action_scenario(self):
    stuff...
    x = thingy_action(request)

会给我一个例外,比如:

Traceback (most recent call last):
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/tests/view_tests.py", line 72, in test_alles
    self.assertRaises(UserNotFound,lambda:get_user(request))
  File "/usr/lib/python2.7/unittest/case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/tests/view_tests.py", line 72, in <lambda>
    self.assertRaises(UserNotFound,lambda:get_user(request))
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/views.py", line 69, in get_user
    oUser = request.context.oUser
AttributeError: 'NoneType' object has no attribute 'thingy_instance'

简言之。在测试中request.context是无。但是当通过他们的url访问视图时,一切正常。你知道吗

例:这种方法适用于新的设置curl -X POST --header 'Accept: application/json' 'http://stuff/kind1/{id1}/kind2/{id2}.../action/'

那么,如何优雅地处理这个问题呢?我想在视图中使用上下文,并通过测试。你知道吗


Tags: instanceinpy视图backendurlgetrequest
1条回答
网友
1楼 · 发布于 2024-06-28 11:41:31

你要找的是功能测试而不是单元测试。在金字塔中,视图本身只是“函数”,不做任何填充上下文的操作等。在所有其他事情发生之后,它们被金字塔的路由器调用。但是你没有在这些测试中使用路由器,所以这些事情都没有发生。你知道吗

如果您只想在单元测试中测试view函数本身,那么您可以拥有测试集request.context = ThingyContext(...),并且您的视图应该是满意的。你知道吗

如果您想测试像curl这样的客户机如何测试它这样的东西,那么您需要使用webtest。你知道吗

from webtest import TestApp

app = config.make_wsgi_app()
testapp = TestApp(app)
response = testapp.get('/')

这将需要一个完整的应用程序,而不仅仅是查看功能。你知道吗

相关问题 更多 >