奇怪的行为mock的side_effect函数

时间:2014-04-25 12:48:42

标签: python unit-testing mocking

我有这段代码:

import postie

def send_mail(self, outbox):
    try:
        postie.postmail(self.dbname, outbox)
    except postie.EmailDeliveryException:
        self.logger.error('Fail to send mail’)
        return False
    return True

我想测试一个postie.EmailDeliveryException引发的情况。 所以我嘲笑postie.postmail并将异常放在其调用的旁边:

import postie

@patch('postie.postmail')
def test_send_mail_False(self, postie_stub):
    ''' Mail send failed '''
    postie_stub.return_value = None
    postie_stub.side_effect = postie.EmailDeliveryException
    op = OutboxProcessor('db name', None, None)
    self.assertFalse(op.send_mail(Outbox()))

以上结果如下:

test_send_mail_False (test_outbox_processor.OutboxProcessorTestCase)
Mail send failed ... No handlers could be found for logger "outbox"
ok

现在我想模拟记录器并检查在“EmailDeliveryException”的情况下是否也调用了错误函数。我走了:

@patch('postie.postmail')
@patch.object(Logger, 'error')
def test_send_mail_False(self, postie_stub, logger_stub):
    ''' Mail sending failed '''
    postie_stub.return_value = None
    postie_stub.side_effect = postie.EmailDeliveryException
    logger_stub.return_value = None

    op = OutboxProcessor('db name', None, None)
    self.assertFalse(op.send_mail(Outbox(), None))
    logger_stub.assert_called()

结果将是:

FAIL: test_send_mail_False (test_outbox_processor.OutboxProcessorTestCase)
Mail sending failed
AssertionError: True is not false

所以看起来assertFalse不再成功,(可能不再引发异常)。任何人都知道在这里是否有任何干扰我的side_effect?提前谢谢!

1 个答案:

答案 0 :(得分:0)

修补程序装饰器(或存根参数)的顺序不正确。以下是mock docs的解释:

  

当您嵌套修补程序装饰器时,模拟传递给   装饰函数按照它们应用的相同顺序(正常的python   命令装饰器应用)。这意味着自下而上......

所以它应该是:

@patch.object(Logger, 'error')
@patch('postie.postmail')
def test_send_mail_False(self, postie_stub, logger_stub):
    ''' Mail sending failed '''