[英]Twisted Trial: How to test a MultiService with a client in it — Reactor was unclean
[英]How to test twisted web resource with trial?
我正在開發一個twisted.web服務器 - 它包含一些資源,除了渲染內容之外,還使用adbapi來獲取一些數據並將一些數據寫入postgresql數據庫。 我試圖弄清楚如何編寫一個試驗單元測試來測試資源渲染而不使用網絡(換句話說:它會初始化資源,產生虛擬請求等)。
讓我們假設View資源是一個簡單的葉子,在render_GET中返回NOT_DONE_YET,並且使用adbapi修飾,以生成簡單的文本。 現在,我已經編寫了這個無用的代碼,我無法提出如何讓它實際初始化資源並產生一些合理的響應:
from twisted.trial import unittest
from myserv.views import View
from twisted.web.test.test_web import DummyRequest
class ExistingView(unittest.TestCase):
def test_rendering(self):
slug = "hello_world"
view = View(slug)
request = DummyRequest([''])
output = view.render_GET(request)
self.assertEqual(request.responseCode, 200)
輸出是...... 1.我也嘗試過這樣的方法:output = request.render(view)但輸出= 1.為什么? 我會為一些例如如何編寫單元測試等非常 gratefull!
這是一個函數,它將呈現一個請求並將結果轉換為在渲染完成時觸發的Deferred:
def _render(resource, request):
result = resource.render(request)
if isinstance(result, str):
request.write(result)
request.finish()
return succeed(None)
elif result is server.NOT_DONE_YET:
if request.finished:
return succeed(None)
else:
return request.notifyFinish()
else:
raise ValueError("Unexpected return value: %r" % (result,))
它實際上在Twisted Web的測試套件中使用,但它是私有的,因為它本身沒有單元測試。 ;)
您可以使用它來編寫如下測試:
def test_rendering(self):
slug = "hello_world"
view = View(slug)
request = DummyRequest([''])
d = _render(view, request)
def rendered(ignored):
self.assertEquals(request.responseCode, 200)
self.assertEquals("".join(request.written), "...")
...
d.addCallback(rendered)
return d
這是一個DummierRequest類,幾乎解決了我所有的問題。 唯一剩下的就是它沒有設置任何響應代碼 ! 為什么?
from twisted.web.test.test_web import DummyRequest
from twisted.web import server
from twisted.internet.defer import succeed
from twisted.internet import interfaces, reactor, protocol, address
from twisted.web.http_headers import _DictHeaders, Headers
class DummierRequest(DummyRequest):
def __init__(self, postpath, session=None):
DummyRequest.__init__(self, postpath, session)
self.notifications = []
self.received_cookies = {}
self.requestHeaders = Headers()
self.responseHeaders = Headers()
self.cookies = [] # outgoing cookies
def setHost(self, host, port, ssl=0):
self._forceSSL = ssl
self.requestHeaders.setRawHeaders("host", [host])
self.host = address.IPv4Address("TCP", host, port)
def addCookie(self, k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None):
"""
Set an outgoing HTTP cookie.
In general, you should consider using sessions instead of cookies, see
L{twisted.web.server.Request.getSession} and the
L{twisted.web.server.Session} class for details.
"""
cookie = '%s=%s' % (k, v)
if expires is not None:
cookie = cookie +"; Expires=%s" % expires
if domain is not None:
cookie = cookie +"; Domain=%s" % domain
if path is not None:
cookie = cookie +"; Path=%s" % path
if max_age is not None:
cookie = cookie +"; Max-Age=%s" % max_age
if comment is not None:
cookie = cookie +"; Comment=%s" % comment
if secure:
cookie = cookie +"; Secure"
self.cookies.append(cookie)
def getCookie(self, key):
"""
Get a cookie that was sent from the network.
"""
return self.received_cookies.get(key)
def getClientIP(self):
"""
Return the IPv4 address of the client which made this request, if there
is one, otherwise C{None}.
"""
return "192.168.1.199"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.