python - 使用 pymox 模拟 urllib2.urlopen 和 lxml.etree.parse

标签 python urllib2 lxml unit-testing mox

我正在尝试测试一些使用 urllib2 和 lxml 的 python 代码。

我看过几篇博客文章和堆栈溢出文章,人们希望使用 urllib2 测试抛出的异常。我还没有看到测试成功调用的示例。

我走的路正确吗?

有人有让它发挥作用的建议吗?

这是我到目前为止所拥有的:

import mox
import urllib
import urllib2
import socket
from lxml import etree

# set up the test
m = mox.Mox()
response = m.CreateMock(urllib.addinfourl)
response.fp = m.CreateMock(socket._fileobject)
response.name = None # Needed because the file name is checked.
response.fp.read().AndReturn("""<?xml version="1.0" encoding="utf-8"?>
<foo>bar</foo>""")
response.geturl().AndReturn("http://rss.slashdot.org/Slashdot/slashdot")
response.read = response.fp.read # Needed since __init__ is not called on addinfourl.
m.StubOutWithMock(urllib2, 'urlopen')
urllib2.urlopen(mox.IgnoreArg(), timeout=10).AndReturn(response)
m.ReplayAll()

# code under test
response2 = urllib2.urlopen("http://rss.slashdot.org/Slashdot/slashdot", timeout=10)
# Note: response2.fp.read() and response2.read() do not behave the same, as defined above.
# In [21]: response2.fp.read()
# Out[21]: '<?xml version="1.0" encoding="utf-8"?>\n<foo>bar</foo>'
# In [22]: response2.read()
# Out[22]: <mox.MockMethod object at 0x97f326c>
xcontent = etree.parse(response2)

# verify test
m.VerifyAll()

它失败了:

Traceback (most recent call last):
  File "/home/jon/mox_question.py", line 22, in <module>
    xcontent = etree.parse(response2)
  File "lxml.etree.pyx", line 2583, in lxml.etree.parse (src/lxml/lxml.etree.c:25057)
  File "parser.pxi", line 1487, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:63708)
  File "parser.pxi", line 1517, in lxml.etree._parseFilelikeDocument (src/lxml/lxml.etree.c:63999)
  File "parser.pxi", line 1400, in lxml.etree._parseDocFromFilelike (src/lxml/lxml.etree.c:62985)
  File "parser.pxi", line 990, in lxml.etree._BaseParser._parseDocFromFilelike (src/lxml/lxml.etree.c:60508)
  File "parser.pxi", line 542, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:56659)
  File "parser.pxi", line 624, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:57472)
  File "lxml.etree.pyx", line 235, in lxml.etree._ExceptionContext._raise_if_stored (src/lxml/lxml.etree.c:6222)
  File "parser.pxi", line 371, in lxml.etree.copyToBuffer (src/lxml/lxml.etree.c:55252)
TypeError: reading from file-like objects must return byte strings or unicode strings

这是因为 response.read() 没有返回我期望的结果。

最佳答案

我根本不会深入研究 urllib2 的内部结构。我认为这超出了你关心的范围。这是使用 StringIO 执行此操作的简单方法。这里的关键是,您打算解析为 XML 的内容只需在鸭子类型方面类似于文件,不需要是实际的 addinfourl 实例。

import StringIO
import mox
import urllib2
from lxml import etree

# set up the test
m = mox.Mox()
response = StringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
<foo>bar</foo>""")
m.StubOutWithMock(urllib2, 'urlopen')
urllib2.urlopen(mox.IgnoreArg(), timeout=10).AndReturn(response)
m.ReplayAll()

# code under test
response2 = urllib2.urlopen("http://rss.slashdot.org/Slashdot/slashdot", timeout=10)
xcontent = etree.parse(response2)

# verify test
m.VerifyAll()

关于python - 使用 pymox 模拟 urllib2.urlopen 和 lxml.etree.parse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3145519/

相关文章:

javascript - 使用 flask 和 javascript 的动态事件源

将字符串映射到一组字符串的 Python 字典?

python - 使用 Python 发布原始数据

python - python中使用POST上传文件。去哪里看?

Python lxml.etree 保留实体引用

带有 lxml 的 Python 漂亮的 XML 打印机

python - lxml etree 解析失败(IOError)

python - 64 位 Python 中的 32 位 float 学运算

python - Django 问题 : Django ManagementForm data is missing or has been tampered with

python urllib2.URL错误处理