我正在使用testfixures log.check()
来验证我的日志记录输出。我的日志语句包含会话和持续时间等可变部分。例如:
2014-02-13T12:04:40.013822 user=user action=do_x session=4a5869aa-f581-4263-a567-918b792587e5 duration=200
我的log.check()
看起来像这样,但目前无效。
...
log.check(
('root', 'INFO', '2014-02-13T12:04:40.013822 user=user action=do_x session=4a5869aa-f581-4263-a567-918b792587e5 duration=200'),
...
是否可以检查第一部分,但允许第二部分使用通配符?
@Edit
@ will-hart道歉,目前的问题是我的日志声明与我的期望不符。我的日志行包括静态文本(键)和变量(值)。问题是在方法中生成了一些值,例如session_id。因此,我无法写出有意义的期望,因为它永远不会与方法中生成的日志语句匹配。
我所追求的几乎是一个“包含”检查,以验证我知道这些值是静态的,我可以模拟。
我实际上已经离开了testfixtures而试图用Mock来实现这一点,通过模拟我的记录器然后调用assert_called_with(“var1 =%s var2 =%s var3 = s%”,var1,var2,var3),但是问题仍然存在,如果var1和var2是从方法调用返回的值,我可以模拟它们,但是让我们说var3是一个时间戳。这是在方法内部生成的,所以在我的测试中,我不想断言val3的值。在Java中,您可以使用any()来匹配任何值。我在Python中找不到任何相同的东西。
答案 0 :(得分:0)
最好的方法是不使用testfixtures,而是模拟我的记录器并传递给Class构造函数,以便我可以模拟它。
所以我的日志语句如下:
self.logger.info("%s user=%s action=%s nodegroup=%s session=%s", datetime.datetime.now().isoformat(), options.username, options.action, options.nodegroup, str(session_id))
在测试中我可以验证输出:
action_log_text = '%s user=%s action=%s nodegroup=%s session=%s'
fin_log_text = '%s %s user=%s action=%s nodegroup=%s session=%s duration=%s'
...
calls = [call(self.action_log_text, ANY, options.username, options.action, options.nodegroup, ANY),
call(self.fin_log_text, ANY, '[FIN]', options.username, options.action, options.nodegroup, ANY, ANY)]
self.logger.info.assert_has_calls(calls)
结果是python mock有任何属性可以匹配任何东西。可爱。