2016-09-13 4 views
0

Я создаю набор классов для тестирования некоторых данных - У меня есть базовый класс Test:Призывая дочерний метод в PHP ООП

class Test { 
    protected $data; 
    public function __construct($data) { 
     $this->data = $data; 
    } 
    public function Run() {} 
} 

, а затем ряд классов, которые проходят испытания, такие как TestForX :

class TestForX extends Test { 
    public function Run() { 
     // do test code 
    } 
} 

Я хочу добавить некоторые моменты в мой метод Run. Я знаю, что могу добавить методы для startTiming и endTiming в мой базовый класс и позвонить parent::startTiming() и parent::endTiming() в своих расширенных классах, но я уже написал массу тестов.

Можно ли включить этот раунд и использовать что-то вроде child::Run в моем базовом классе?

class Test { 
    public function Run() { 
     $this->startTime = microtime(true); 
     child::Run(); 
     $this->endTime = microtime(true); 
    } 
} 

Это позволило бы мне сохранить классы моего ребенка чистыми, обернув методы в основании. На данный момент я обойду его, имея базовый класс для Test::Go, который вызывает $this->Run().

+0

Это не похоже на phpunit. Имеет ли ваша среда тестирования концепция метода метода startUp() и tearDown()? Если это так, я бы поместил его в базовый класс, хотя вы бы несли временные издержки из самой тестовой среды. –

+0

Спасибо, но это за тестирование структуры документа - например, DOM - не модульное тестирование. –

+0

FWIW, ваш класс 'Test' не должен иметь метод под названием' Test'; это старый, но все еще поддерживаемый способ объявить конструктор и однажды укусит вас в заднем конце. – deceze

ответ

1

Если вы можете изменить вызов тестовых классов, вы можете добавить другую функцию, которая оборачивает свое поведение

public function runTest(){ 
    $this->startTime = microtime(true); 
    $this->Test(); 
    $this->endTime = microtime(true); 
} 
+0

Спасибо, но в моем вопросе я сказал, что это то, что я сейчас делаю. –

+1

Я считаю, что Джоффри предложил добавить 'runTest()' в родительский класс. –

+0

@AlexBlex в моем вопросе, я описываю «имеющий базовый класс для Test :: Go, который вызывает $ this-> Run()» - я действительно ценю усилия Джоффри, но он дублирует то, что я уже сказал , –

1

Я считаю, что это не возможно вызвать метод ребенка, которые имеют такое же имя, родительский. Прежде всего, это плохой дизайн, предполагающий, что дочерний класс переопределяет метод. Чтобы внедрить дочерний класс для реализации метода, необходимо определить родительский абстрактный метод, но в этом случае вы просто не можете. Метод Run() уже реализован в родительском классе.

Вы должны использовать абстракцию и использовать другое имя.

Вот возможная реализация, которая может сработать для вас. Вы можете просто определить базовый класс как абстрактный класс, TestForX продлит Тест класс и вы будете называть Run() на экземпляре TestForX.

abstract class Test { 
    protected $data; 
    abstract public function RunChild(); 

    public function __construct($data) { 
     $this->data = $data; 
    } 
    public function Run() { 
     $this->startTime = microtime(true); 
     $this->RunChild(); 
     $this->endTime = microtime(true); 
    }  
} 

class TestForX extends Test { 
    public function RunChild() { 
     // do test code 
    } 
} 
Смежные вопросы