PHPunit - 测试用户错误状态的最佳实践(非例外)

时间:2016-10-01 18:59:03

标签: php phpunit

我有一个相当硬的PHP应用程序,我正在重构并添加phpunit测试。应用程序中的常见情况是用户警告消息,用于错误配置(应用程序接收配置文件并生成图像和HTML作为输出)。

所以我在应用程序中散布了一堆代码:

for (auto it = mySet.begin(); it != mySet.end();  
{
    std::cout << **it << std::endl;
    myVector.push_back(std::move(
        mySet.extract(it++).value()));
}

其中wm_warn根据上下文写入stderr或logfile。

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

重要的是 - 这不是一个致命的错误,所以不可能(AFAIK)用例外替换它并使用phpunit&#34;预期的异常&#34;特征

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

2 个答案:

答案 0 :(得分:1)

Mocking可能是正确的解决方案,PHPUnit手册描述了这样的模拟:

  

使用验证的测试双精度替换对象的做法   期望,例如断言已经调用了一个方法,是   被称为嘲弄。

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

您可以在PHPUnit 测试双打主题下阅读有关Simple Mocking的更多信息,该主题显示了此示例(还讨论了上述引用)。您可能面临的一个问题是您可以模拟对象而不是直接函数 - 因此取决于应用程序的硬度:)

答案 1 :(得分: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']);

这非常难看,特别是使用全局变量,但是如果它意味着你设法进行了测试,那么将来会有更多机会重构它并找到更优雅的解决方案。