這裏是我的情況:使用反射來設置的屬性在單元測試
我創建了一個抽象類,以減少重複代碼,並執行由該擴展這個類的具體類實現的一些方法。
abstract class BaseClass { protected $arrayField; ... public function getModifiedArrayField($constraints) { // do things to $arrayField and return a modified // version of the arrayField. Depends only on the // $constraints and some `array_*` functions return $modifiedArray; } // ... some other methods for reducing code duplication // ... abstract methods that needs to be implemented }
我認爲這將是檢驗在抽象類本身的具體方法是個好主意。
$arrayField
將由具體類中的抽象方法填充。
因爲我想測試修改該屬性(但不會改變)的方法的功能,所以我寫了如下的單元測試。現在
class BaseClassTest extents PHPUnit_Framework_TestCase private $sut; public function setUp() { $mockObj = $this->getMockFromAbstractClass(BaseClass::class); $ref = new ReflectionClass($mockObj); $ref_prop = $ref->getProperty('arrayField'); $ref_prop->setAccessible(true); $ref_prop->setValue($mockObj, [an_array]); $this->sut = $mockObj; } // .. some test methods that tests methods of abstract class public function testGetModifiedArrayFieldReturnsExpectedArray() { $expected = [array_i_expect]; $actual = $this->sut->getModifiedArrayField([constraints_i_provide]); $this->assertEquals($expected, $actual); }
,我看這不是使用反射來改變只是爲了測試的緣故知名度一個很好的做法。
所以我兩個問題:
- 是否測試社區發現這種方法只是一個「小過失」,而不是一個大罪?
- 我應該不同地設計這個類,以便我可以擺脫反射?如果是的話,你會建議任何方法?
UPDATE:
的answer通過Schleis讓我思考,並在互聯網上一些聊天與我的朋友和一些資源後,我選擇引入一個額外的參數的函數來解決這個問題我需要測試。
我將繼續嘗試將函數泛化並將其移動到ArrayHelper類的類中,該類使1)測試更容易,2)允許代碼的其他部分在需要時使用該方法。
感謝您的回答。關於你的問題:抽象方法就像一個水化器,它從數據提供者中填充'arrayField'的值。我想測試的方法只是將數據轉換爲不同的格式,以便預先存在的代碼庫可以對返回的數據執行其操作。我想一個更好的想法是將轉換移動到一個單獨的類,並在任何此類返回時運行該轉換,或者只是向該函數傳遞一個額外的參數,儘管我不太確定這種性能開銷。 – cipher