2013-07-12 53 views
3

说我有一类叫做客户端创建Request类的一个对象,并把它传递给Connection对象的一个​​方法的对象:断言传递到在Python一个模拟的方法模拟

class Client(object): 
    def __init__(self, connection): 
     self._conn = connection 

    def sendText(plaintext): 
     self._conn.send(Request(0, plaintext)) 

我想要断言传递给Connection.send方法的对象来检查它的属性。我开始创建一个嘲笑Connection类:

conn = Mock() 

client = Client(conn) 
client.sendText('some message') 

然后,我想是这样的:

conn.send.assert_called_with(
    (Request, 
    {'type': 0, 'text': 'some message'}) 
) 

在哪里“类型”和“文本”是请求的性质。有没有办法在python的模拟中做到这一点?我在文档中找到的只是简单的数据示例。 我可以通过与断言对象的字段的方法取代原来的“发送”法mock.patch装饰做到了:

def patchedSend(self, req): 
    assert req.Type == 0 

with mock.patch.object(Connection, 'send', TestClient.patchedSend): 
    ... 

但在这种情况下,我必须定义一个separete嘲笑功能为每方法检查,如果函数已被调用,则无法检查(无需额外编码)。

回答

5

,您就能获得最后的参数模拟与

request, = conn.send.call_args 

,然后断言有关的属性。如果你想让设施表达更复杂的关于事物的断言,你可以安装PyHamcrest

注意:请勿在单元测试中使用assert。使用断言方法,如assertEqualassertTrue。断言方法不会意外关闭,并且它们可以提供比assert语句更有用的消息。

+0

这就是我需要的。谢谢。 –

1

嗯,我认为在这个特定情况下,最简单和最好的方法是创建一个函数来创建请求,然后对其进行嘲弄。

举例来说,这将会是类似的东西:

class Client(object): 
    def __init__(self, connection): 
     self._conn = connection 

    def _create_request(self, plain_text): 
     return Request(0, plain_text) 

    def send_text(self, plaintext): 
     self._conn.send(self._create_request(plain_text)) 

然后,在测试中,你可以嘲笑_create_request返回一些特定的值,然后断言send_text被称为它。

您也可以按照建议通过call_args获取参数,但我认为这样看起来更好。