为扭曲的应用程序编写单元测试。使用新的连接(协议实例)解决了一旦延迟就尝试执行一些断言的问题,但是看到同时触发了成功和错误回调(通过在控制台中打印SUCCESS
和FAIL
来判断) 。
def test_send_to_new_connection(self):
# Given
peerAddr = ('10.22.22.190', 5060)
# If
self.tcp_transport.send_to('test', peerAddr)
# Then
assert peerAddr in self.tcp_transport._connections
assert True == isinstance(self.tcp_transport._connections[peerAddr], Deferred)
connection = _string_transport_connection(self.hostAddr, peerAddr, None, self.tcp_transport.connectionMade)
def assert_cache_updated_on_connection(connection):
print('--------- SUCCESS ----------')
peer = connection.transport.getPeer()
peerAddr = (peer.host, peer.port)
assert peerAddr in self.tcp_transport._connections
assert True == isinstance(self.tcp_transport._connections[peerAddr], Protocol)
def assert_fail(fail):
print('--------- FAIL ----------')
self.tcp_transport._connections[peerAddr].addCallback(assert_cache_updated_on_connection)
self.tcp_transport._connections[peerAddr].addErrback(assert_fail)
# Forcing deferred to fire with mock connection
self.tcp_transport._connections[peerAddr].callback(connection)
我认为执行Callbacks和Errbacks是互斥的。即根据延迟的分辨率,只有其中一个会运行。为什么还assert_fail()
被呼叫?
答案 0 :(得分:1)
请参见Deferred Reference中的“铁路”图:
注意从回调方到错误背方,反之亦然有对角箭头。在回调/错误返回链中的任何一个单个位置(其中“位置”是并排放置的一对盒子,一个绿色和一个红色,位置随着位置的增加而增加)只会调用回调或errback之一。但是,由于链中有多个位置,因此您可以在单个Deferred上调用许多回调和许多errback。
对于您的代码:
....addCallback(assert_cache_updated_on_connection)
....addErrback(assert_fail)
有两个职位。第一个具有回调,第二个具有错误。如果回调信号指示失败,则执行将切换到下一个位置的errback端-正是您拥有assert_fail
的位置。