序列化twisted.protocols.amp.AmpList进行测试

时间:2014-02-23 23:08:19

标签: python twisted asynchronous-messaging-protocol

我有一个如下命令:

class AddChatMessages(Command):

    arguments = [ 
        ('messages', AmpList([('message', Unicode()), ('type', Integer())]))]

我在控制器中有响应者:

def add_chat_messages(self, messages):
    for i, m in enumerate(messages):
        messages[i] = (m['message'], m['type'])
        self.main.add_chat_messages(messages)
    return {}
commands.AddChatMessages.responder(add_chat_messages)

我正在为它编写单元测试。这是我的代码:

class AddChatMessagesTest(ProtocolTestMixin, unittest.TestCase):
    command = commands.AddChatMessages
    data = {'messages': [{'message': 'hi', 'type': 'None'}]}

    def assert_callback(self, unused):
        pass

ProtocolMixin如下:

class ProtocolTestMixin(object):

    def setUp(self):
        self.protocol = client.CommandProtocol()

    def assert_callback(self, unused):
        raise NotImplementedError("Has to be implemented!")

    def test_responder(self):
        responder = self.protocol.lookupFunction(
            self.command.commandName)
        d = responder(self.data)
        d.addCallback(self.assert_callback)
        return d

如果不涉及AmpList,它会起作用,但是当它出现时 - 我得到以下错误:

======================================================================
ERROR: test_responder
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/internet/defer.py", line 139, in maybeDeferred
    result = f(*args, **kw)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/internet/utils.py", line 203, in runWithWarningsSuppressed
    reraise(exc_info[1], exc_info[2])
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/internet/utils.py", line 199, in runWithWarningsSuppressed
    result = f(*a, **kw)
  File "/Users/<username>/Projects/space/tests/client_test.py", line 32, in test_responder                                                                             
    d = responder(self.data)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1016, in doit
    kw = command.parseArguments(box, self)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1717, in parseArguments
    return _stringsToObjects(box, cls.arguments, protocol)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 2510, in _stringsToObjects
    argparser.fromBox(argname, myStrings, objects, proto)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1209, in fromBox
    objects[nk] = self.fromStringProto(st, proto)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1465, in fromStringProto
    boxes = parseString(inString)
  File "/Users/<username>/Projects/space/env/lib/python2.7/site-packages/twisted/protocols/amp.py", line 2485, in parseString
    return cls.parse(StringIO(data))
TypeError: must be string or buffer, not list

哪个有意义,但如何在AddChatMessagesTest.data中序列化列表?

1 个答案:

答案 0 :(得分:2)

响应者期望使用序列化框调用。然后它将反序列化它,将对象分派给应用程序代码,获取应用程序代码返回的对象,序列化它,然后返回该序列化的表单。

适用于少数AMP类型。最值得注意的是String,序列化形式与反序列化形式相同,因此很容易忽略这一点。

我认为您希望通过Command.makeArguments传递数据,以便生成适合传递给响应者的对象。

例如:

>>> from twisted.protocols.amp import Command, Integer
>>> class Foo(Command):
...     arguments = [("bar", Integer())]
... 
>>> Foo.makeArguments({"bar": 17}, None)
AmpBox({'bar': '17'})
>>>

如果您使用使用Command的{​​{1}}执行此操作,我认为您会发现AmpList会返回该参数值的编码字符串,并且响应者很乐意接受并解析那种字符串。