python StringIO与urlli2.urlopen使用unittest进行模拟

时间:2012-08-29 23:40:43

标签: python unit-testing mocking

我有一个有趣的问题。我用python模拟库嘲笑urllib2.urlopen如下:

def mock_url_open_conn_for_json_feed():
    json_str = """
        {"actions":[{"causes":[{"shortDescription":"Started by user anonymous","userId":null,"userName":"anonymous"}]}],"artifacts":[],"building":false,"description":null,"duration":54,"estimatedDuration":54,
        "fullDisplayName":"test3#1",
        "id":"2012-08-24_14-10-34","keepLog":false,"number":1,"result":"SUCCESS","timestamp":1345842634000,
        "url":"http://localhost:8080/job/test3/1/","builtOn":"","changeSet":{"items":[],"kind":null},"culprits":[]}
        """
    return StringIO(json_str)

def test_case_foo(self):
    io = mock_url_open_conn_for_json_feed()
    io.seek(0)
    mylib.urllib2.urlopen = Mock(return_value=io)
    test_obj.do_your_thing()

def test_case_foo_bar(self)
    io = mock_url_open_conn_for_json_feed()
    io.seek(0)
    mylib.urllib2.urlopen = Mock(return_value=io)
    test_obj.param = xyz
    test_obj.do_your_thing()

class ObjUnderTest():
    def do_your_thing(self):
        conn = urllib2.urlopen(url)
        simplejson.load(conn)

第一个单元测试“test_case_foo”运行没有问题。但是simplejson.load会关闭StringIO,所以“test_case_foo_bar”调用do_your_thing()并尝试simplejson.load相同的StringIO对象(即使我返回StringIO的构造函数),它已经被关闭。我收到以下错误:

json = simplejson.load(conn)
 File "/Users/sam/Library/Python/2.7/lib/python/site-packages/simplejson/__init__.py", line 391, in load
return loads(fp.read(),
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/StringIO.py", line 127, in read
_complain_ifclosed(self.closed)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/StringIO.py", line 40, in _complain_ifclosed
raise ValueError, "I/O operation on closed file"
ValueError: I/O operation on closed file

我有两个问题:

1)为什么StringIO构造函数没有返回新对象?

2)有解决方法吗?或者更好的方法来实现我想要实现的目标?

0 个答案:

没有答案