2016-10-01 70 views
1

我有一个相当脆弱的PHP应用程序,我正在重构并为我添加phpunit测试。应用程序中的一个常见情况是用户警告消息的错误配置(应用程序接收配置文件并生成图像和HTML作为输出)。PHPunit - 测试用户错误状态的最佳实践(不是例外)

所以我必须通过像应用洒一串代码:

wm_warn("You can't make a contrast with 'none' - guessing black. [WMWARN43]\n"); 

其中wm_warn其写入标准错误或根据上下文的日志文件。

如何使用phpunit测试这些警告?

重要的是 - 这不是一个致命的错误,所以它是不可能的(AFAIK)用一个例外来代替它,并使用phpunit的“预期异常”功能。

这是一个wm_warn模拟的用例吗?或者捕获stderr?或者使用不同的日志记录方法来简化测试(例如log4php)?

回答

1

嘲讽可能是正确的解决方案中,PHPUnit的手册描述嘲笑这样:

与测试两倍验证 期望,例如断言一方法被调用替换对象的实践中,被称为嘲笑的是 。

所以你可以观察到wm_warn被调用,但它没有执行(没有任何进入日志)。

可以PHPUnit的测试双打话题,显示了这样的一个实例(这里还讨论了上述报价)下阅读更多关于Simple Mocking。你可能会遇到的一个问题是,你可以嘲笑物体,但不是直接的功能 - 这取决于你的应用程序的硬壳:)

+1

谢谢,写得不错!当前的日志函数是一个实际的函数,但我可以很容易地调用一个日志对象的方法(以便将其全部折叠为直接调用日志记录对象)。 – AnotherHowie

+0

@AnotherHowie很高兴听到它可以为你工作! – Katie

1

嘲笑(或更确切地说间谍)将是前进的道路..它可能很难实现,这取决于应用程序(你说它相当硬皮)

函数如何加载?如果可以拦截包含wp_warn函数的相关文件的调用,则可以改为使用自己的模拟版本,然后可以将调用的参数(即错误)记录到(urgh,shudder) )全局变量是测试用例访问:

//... 
if (defined('TEST_ENVIRONMENT')) { 
    require_once 'wp_warn-test.php'; 
} else { 
    require_once 'wp_warn.php'; 
} 
//... 

在wp_warn-test.php的:

function wp_warn($error) 
{ 
    $_GLOBALS['SPY_WP_WARN_ERRORS'][] = $error; 
} 

,并在测试:

$this->assertContains("You can't make a contrast with 'none' - guessing black. [WMWARN43]\n", $_GLOBALS['SPY_WP_WARN_ERRORS']); 

这非常丑陋,尤其是在使用全局变量的情况下,但如果它意味着您设法进行测试,那么您将有更多机会重构它并找到更优雅的解决方案。

+0

wm_warn可以在一个单独的文件中(它目前不是)。我想我会随它一起调用全局日志记录对象中的方法,然后可以进行模拟和替换。还有一些其他的loglevels(调试,跟踪)也应该在一个地方处理。我已经想过要有某种LogObjectFactory,因此在非调试模式下,debug()调用尽可能短,而不同的日志对象具有存根函数。 – AnotherHowie