Почему статические методы являются неустойчивыми?

Почему статические методы являются неустойчивыми? Пожалуйста, продемонстрируйте (в PHP, если это возможно).

Ответ 1

Статические методы сами по себе не являются неопровержимыми, но если тестируемый объект вызывает статический метод, тогда тест не может "поселиться" между ними и заставить его вместо этого вызвать метод заглушки. Если тестируемый объект вместо этого вызывает обычный метод, тест может дать ему альтернативный объект с реализацией этого заглушки.

В общем, жесткие зависимости менее проверяемы, в то время как инъекция зависимостей (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);
    }
}

Ответ 2

Статические методы можно тестировать: http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html (это в php), но если вы хотите протестировать взаимодействие между классами (то есть используя mocks и поддельные объекты), вы, вероятно, предпочтете не использовать его. Это означает, что phpunit 3.5 позволяет их заглушить.

Вы также можете посмотреть Когда использовать статические переменные/функции в php? или искать некоторую информацию о том, когда использовать статические методы.

Я использую статические методы внутри класса (т.е. помечен как private или protected), поскольку они быстрее работают на языке, с которым я работаю.

Ответ 3

Хорошо определенные методы Static отлично проверяются. Видите ли, проблема заключается не в самом методе, а в зависимости от метода. Если метод и его зависимости (и зависимости зависимостей) idempotent, тогда проблем нет. Проблемы возникают, когда ваши методы Static вызывают другие методы, которые, например, зависят от global.