2012-12-18 53 views
21

在每次測試之前和之後調用方法setUp()tearDown()。但是,真的,有什麼真正的例子說明爲什麼我需要這個?有關在PHPUnit中如何使用setUp()和tearDown()的真實例子?

檢查其他人的測試中,我總是看到這樣的:

public function setUp() 
{ 
    $this->testsub = new TestSubject(); 
} 

public function tearDown() 
{ 
    unset($this->testsub); 
} 

public function testSomething() 
{ 
    $this->assertSame('foo', $this->testsub->getFoo()); 
} 

當然,也幾乎是這樣的,「舊」的局部變量的方式沒有什麼區別。

+0

所不同的是,你只需要設置一次代碼,無論多少測試,我們在您的測試類 –

+0

@MarkBaker所以...只是當創建測試主題需要很多行時,例如? – gremo

+0

一個很好的例子就是設置一個數據庫表並在完成測試後再次銷燬它。 – busypeoples

回答

16

如果您單獨執行每個測試方法,您的測試代碼將共享很多簡單地創建要測試的對象的行。這個共享代碼可以(但不應該)進入設置方法。即需要做來創建對象

任何待然後測試也進入設置方法,例如創建被注入到測試對象的構造模擬對象。需要被撕開了,因爲設置的下一次調用將一組新的對象初始化類的成員變量

沒有這一點。

需要拆除的唯一的事情是,如果你的測試離開背後的東西永遠,就像得到了創建的文件或數據庫條目。這真的是不寫的是做這樣的事情測試一個很好的想法,但在某些時候,你不能再抽象,並有觸摸的東西,如硬盤,數據庫或實際網絡。

所以有比需要拆卸有更多的設置,我總是刪除的拆卸方法,如果沒有這個測試工作要做。

關於嘲弄,我的工作是這樣的:

private $_mockedService; 
private $_object; 
protected function setUp() 
{ 
    $this->_mockedService = $this->getMock('My_Service_Class'); 
    $this->_object = new Tested_Class($this->_mockService); 
} 

public function testStuff() 
{ 
    $this->_mockedService->expects($this->any())->method('foo')->will($this->returnValue('bar')); 
    $this->assertEquals('barbar', $this->_object->getStuffFromServiceAndDouble()); 
} 
+1

感謝您對'tearDown()'的澄清... – gremo

+0

tearDown()在這裏是缺少的,但基本上你會解除任何需要清除的東西,類似於desctructor 。 –

+1

@StevenScott沒有,'拆解()'是不是故意在我的代碼,因爲'設置()'無論如何都會覆蓋任何東西。無需編寫一個將NULL寫入該測試類的任何私有屬性的拆卸函數。 – Sven

4

您可以實例化一堆燈具對象,並在每次測試中將它們作爲實例變量使用,而不是爲每個測試單獨構建它們。

您可以在setUp中創建類似文件句柄的資源,然後確保在tearDown中關閉它們。如果你正在編寫臨時文件,你可以確保你刪除它們。如果你打開一個數據庫連接,你可以關閉它(儘管你可能在想這樣做,其他地方 - setupBeforeClass/tearDownAfterClass它被調用每一個測試文件,而不是爲每個測試用例)

這只是一個前/掛機後這是一般的常規事情。用它來使你的生活更輕鬆,或者不使用它。

+2

+1「使用它可以使您的生活更輕鬆,或者不使用它。」 setUp()只是一個重構工具,用於共享_common_代碼。只有在有意義時才使用它;不要強制所有燈具的製作進行,因爲每個測試都需要一個稍微不同的燈具! –

1

幾乎在任何時候您都可以在您正在測試的課程中使用該依賴項。一個經典的例子可能是某種存儲應用程序狀態的對象(會話對象,購物車等)。

舉例說,我有一個班級計算購物車對象定義的購物車內容的運費。假設這個購物車通過依賴注入傳遞到運輸計算類中。要測試該類的大多數方法,您可能需要實際實例化一個購物車對象並將其設置在類中,以便對各種方法進行單元測試。您可能還需要將物品添加到購物車中。所以,你可能會有這樣的設置:

public function setUp() 
{ 
    $this->cart = new cart(); 
    $this->cart->add_item('abc'); 
    $this->cart->add_item('xyz'); 
} 

讓我們假設你的測試方法實際上可能會改變購物車的物品,與運輸成本信息裝飾他們。您不希望一次測試的信息流入下一個測試,所以您最後只需將購物車取消。

public function tearDown() 
    unset($this->cart); 
} 
+0

您需要實例化購物車的MOCK,它將返回您在班級中測試計算所需的值。設置一個真正的購物車可能太複雜,因爲它有自己的依賴關係,而且你無法測試購物車是否被正確的參數和方法調用。 – Sven

+0

@Sven我會同意一個模擬車實際上是最好的。我想簡單地說明,會給一個想法,以安裝程序的'實用程序的使用情況()'和'拆解()',而無需引入更先進的單元測試的概念。也許我沒有在這裏選擇最好的例子:) –

相關問題