2014-02-23 32 views
2

我有一个命令如下:序列化twisted.protocols.amp.AmpList测试

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

回答

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'}) 
>>> 

如果你这样做与使用AmpList我想你会发现makeArguments返回一个字符串编码为参数的值和响应者乐于接受和Command解析这种字符串。