我有一个相当硬的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)?
答案 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']);
这非常难看,特别是使用全局变量,但是如果它意味着你设法进行了测试,那么将来会有更多机会重构它并找到更优雅的解决方案。