如何使用phpunit4.6.6及更高版本模拟静态函数

如何使用phpunit4.6.6及更高版本模拟静态函数,php,mocking,phpunit,Php,Mocking,Phpunit,我知道staticExpects在PHPUnit 3.8中已经被弃用,并将在以后的版本中被完全删除。 但是在我们的项目中,到处都使用静态函数。所以,制作phpunit是一个大问题。在我们的开发中,phpunit版本是4.6.6,我不能回到3.8。 我的问题是我怎样才能像你一样? 代码: 在一般情况下,您可以不模拟静态函数调用。如果您打算用mock测试您的软件,请不要使用静态调用。你可以尝试和摆弄邪恶的把戏,但这通常是一个巨大的痛苦 您可能没有彻底阅读PHPUnit的staticExpects特性

我知道staticExpects在PHPUnit 3.8中已经被弃用,并将在以后的版本中被完全删除。 但是在我们的项目中,到处都使用静态函数。所以,制作phpunit是一个大问题。在我们的开发中,phpunit版本是4.6.6,我不能回到3.8。 我的问题是我怎样才能像你一样? 代码:


在一般情况下,您可以不模拟静态函数调用。如果您打算用mock测试您的软件,请不要使用静态调用。你可以尝试和摆弄邪恶的把戏,但这通常是一个巨大的痛苦

您可能没有彻底阅读PHPUnit的staticExpects特性的文档。它不能满足你的需要。塞巴斯蒂安在phpunit3.5中实现了这个特性,但它并没有像他预期的那样工作,因为人们不理解它的局限性。因此,它在3.8中再次被删除


面对这样一个事实:您使用静态调用创建了不稳定的软件。开始扔掉它们,并通过这种方式提高软件的可测试性。这很痛苦,而且需要花费时间,但这是唯一的方法。

要做到这一点,您需要使用这样的扩展,它允许您在运行时重新定义函数和方法

在测试类中,您将添加如下内容:

public static function setupBeforeClass()
{
    uopz_backup("A", "staticfun");
    uopz_function("A", "staticfun", function () {
        // do something else
    });
}

public static function tearDownAfterClass()
{
    uopz_restore("A", "staticfun");
}
这将:

  • 备份原始方法
  • 将其重新定义为给定闭包
  • 当类中的测试完成时恢复原始

项目的时代不会改变静态方法无法模拟的事实。您仍然可以调用它们并检查返回值。您还可以尝试将它们封装在实例化对象中,这些对象只是将调用转发给静态函数。然后可以模拟该对象。修复它还有很长的路要走,但是如果项目是旧的和不稳定的,要么不要碰它,要么接受改变它会产生无法测试的错误。@Paul:现在uopz_备份等等。。PECL uopz 5.0.0中不推荐使用函数,替代解决方案是什么。
public static function setupBeforeClass()
{
    uopz_backup("A", "staticfun");
    uopz_function("A", "staticfun", function () {
        // do something else
    });
}

public static function tearDownAfterClass()
{
    uopz_restore("A", "staticfun");
}