为什么静态方法不可测试?

时间:2012-07-21 10:56:42

标签: php unit-testing static-methods

为什么静态方法不可测试?请举例说明(如果可能,请使用PHP)。

3 个答案:

答案 0 :(得分:10)

静态方法本身并不是不可测试的,但如果被测试的对象调用静态方法,则测试不能“介入”并使其调用存根方法。如果正在测试的对象调用常规方法,则测试可以为其提供具有该方法的存根实现的替代对象。

一般情况下,严格的依赖关系不太可测试,而依赖注入(google it)会使代码更易于测试。

例如,假设我们正在测试的类使用静态方法getCurrentUser(),如下所示

class PostModel {
    //...
    public function getRecentPosts() {
        return $this->database->from('posts')
                ->where(array('user' => UserModel::getCurrentUser()))
                ->limit(10);
    }
}

现在UserModel::getCurrentUser()不能用存根方法替换。如果我们使它成为我们通过对象引用调用的常规方法,我们可以在测试中传入一个替代存根对象。

class PostModel {
    private $userModel;
    public function __construct($userModel) { 
        $this->userModel = $userModel;
    }
    //...
    public function getRecentPosts() {
        return $this->database->from('posts')
                ->where(array('user' => $this->userModel->getCurrentUser()))
                ->limit(10);
    }
}

答案 1 :(得分:4)

静态方法是可测试的:http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html(它在php中),但是如果你想测试类之间的交互作用(即使用模拟和虚假对象),你可能更愿意不使用它。据说phpunit 3.5允许你存根这些。

您可能还想查看When do I use static variables/functions in php?或搜索有关何时使用静态方法的一些信息。

我在类中使用静态方法(即标记为private或protected),因为它们在我使用的语言中更快。

答案 2 :(得分:1)

明确定义的Static方法是完全可测试的。你看,问题不在于方法本身,而在于方法的依赖性。如果方法及其依赖项(以及依赖项的依赖项)是idempotent,那么就没有问题。当Static方法调用其他方法(例如,依赖于global)时会出现问题。