2014-02-07 111 views
1

在Yii我想對使用ActiveRecord對象的類執行一些單元測試。例如,我有一個翻譯ActiveRecord。當我嘗試爲它創建一個模擬對象時,我得到一個錯誤。如何模擬Yii中的ActiveRecord對象?

在我的測試中,我也行:

$translation = $this->getMock("Translation"); 

,然後當我運行我的測試中,我得到這個錯誤:

PHPUnit 3.7.30 by Sebastian Bergmann. 

Configuration read from /Users/riverstyx/Sites/protected/tests/phpunit.xml 

E. 

Time: 1.27 seconds, Memory: 6.25Mb 

There was 1 error: 

1) TranslationManagerTest::testCreateNewTranslation 
Trying to get property of non-object 

/Users/riverstyx/yii/framework/db/ar/CActiveRecord.php:79 
/Users/riverstyx/Sites/protected/tests/unit/TranslationManagerTest.php:8 

FAILURES! 
Tests: 2, Assertions: 0, Errors: 1 

我理解Yii中使用夾具但我不的概念我不想依賴數據庫來做我的測試。我們在生產中使用MySQL,因此創建臨時內存中的SQLITE數據庫似乎很奇怪,因爲它與我們實際的MySQL環境不匹配,並且還存在一些語法細微差別(即UTC_TIMESTAMP()不存在於SQLITE中)。

理想情況下(和所有的單元測試一樣),我想測試我的TranslationManager類與活動記錄隔離。

任何幫助,將不勝感激:)

+0

您可以顯示測試的其餘部分嗎? – vascowhite

+0

解決了! ()「>) - > disableOriginalConstructor() - > getMock();這個方法可以用來創建一個數組。需要 disableOriginalConstructor所以它不會調用原始的構造函數(這是造成問題的原因) 還需要調用setMethods並明確列出我正在重寫功能,使ActiveRecord的的魔術方法仍然將保持不變 – John

回答

1

想通了......

$this->getMockBuilder("Translation") 
    ->setMethods(array("getIsNewRecord", "save")) 
    ->disableOriginalConstructor() 
    ->getMock(); 

當「翻譯」是我的活動記錄模型的名稱。你必須使用setMethods來識別你將要模擬的方法,以便其他屬於活動記錄的方法保持不變。這很重要,這樣默認的__get和__set魔術方法仍然可以正常工作。

「disableOriginalConstructor」是正確構建主動記錄對象所必需的

+0

呀,不幫助我。我仍然得到: '致命錯誤:嘗試訪問屬性時,在第135行的.. \ yii2 \ db \ ActiveRecord.php中的非對象上調用成員函數getDb()。 –