Макетировать функцию объекта, созданного статическим методом в PHP? - PullRequest
0 голосов
/ 24 марта 2012

Я использую ORM, а способ получения объекта записи - FooModel::find(1).FooModel есть метод, который мне нужно смоделировать для тестирования.Как мне это сделать?(Невозможно использовать PHPUnit mock, потому что это дало бы мне поддельное FooModel, которое не будет соответствовать записи с идентификатором 1.)

Редактировать

Пример:

class FooModel
{
    // ORM model that fetches record from the DB

    public function thisNeedsToBeMocked()
    {
        // some code here that depends on external factors so should be part of unit tests
    }
}

Способ, которым я получаю запись с идентификатором 1:

$fooObject = FooModel::find(1);

Мне нужно иметь возможность высмеивать thisNeedsToBeMocked() из $fooObject, который у меня послеЯ запускаю static метод find().

1 Ответ

0 голосов
/ 24 марта 2012

Вы столкнулись с классической проблемой модульного тестирования. Имя класса, которое вы используете для статического вызова, является частью глобального пространства имен. Это означает, что нет смысла вставлять макет. Это не магия, которую вы можете сделать здесь, чтобы решить эту проблему, вам придется внести некоторые изменения в код.

Есть много способов решить это, и есть много против и против каждого из них. Я дам вам простое хакерское решение. Если вы хотите что-то другое, дайте мне знать, и я напишу пример.

Я также предполагаю, что вы не можете изменить ORM, основываясь на статических классах.

Вот хакерский подход, который очень плохой способ делать вещи, так что вы знаете. В вашем классе должна быть переменная, которая является именем класса ORM, который вам нужно использовать. Это код PHP 5.3.

Вот так:

<?php

class Bar {
    public static $ormName = 'FooModel';

    public static function doStuff()
    {
        $className = self::$ormName;
        echo $className::find(1), "\n";
    }
}

Затем в вашем тесте PHPUnit создайте макет. Получите его имя класса, установите это имя класса для вашего испытуемого. Теперь ваш испытуемый будет называть вашу ложь.

Есть много способов решить эту проблему, но есть некоторые, как вам нужен способ не использовать имя класса напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...