2015-07-23 17 views
6

Tôi biết có thể thử nghiệm các phương pháp riêng tư/được bảo vệ bằng PHPUnit bằng cách sử dụng phản ánh hoặc cách giải quyết khác.Phạm vi mã khi không thử nghiệm các phương pháp được bảo vệ/riêng tư với PHPUnit

Nhưng hầu hết các nguồn cho tôi biết rằng đó là không phải là thực hành tốt nhất để viết các thử nghiệm cho các phương thức riêng tư bên trong một lớp học.

Bạn phải kiểm tra lớp như thể nó là "hộp đen" - bạn chỉ cần kiểm tra hành vi mong đợi bằng cách so sánh các đầu vào với đầu ra không quan tâm đến cơ chế bên trong. Các bài kiểm tra viết cho các lớp cũng sẽ thông báo cho bạn về các phương thức riêng không được sử dụng, bằng cách hiển thị thiếu mức độ bao phủ mã.

Khi tôi kiểm tra lớp của mình và tạo báo cáo HTML, nó hiển thị các phương thức riêng tư không được kiểm tra, mặc dù các dòng mà từ đó chúng được gọi là hoàn toàn được thực hiện/được bảo vệ. Tôi biết rằng các phương pháp riêng được thực hiện, bởi vì nếu chúng không phải là các xác nhận trên lớp của tôi sẽ không vượt qua.

Hành vi này có được mong đợi trong PHPUnit không? Tôi có thể cố gắng bảo hiểm 100%, trong khi vẫn thử nghiệm các phương thức riêng chỉ gián tiếp không?

Một số mã ví dụ đơn giản (sử dụng RestBundle trong Symfony2):

class ApiController extends FOSRestController { 

/* 
* @REST\View() 
* @REST\Get("/api/{codes}") 
*/ 
public function getCodesAction($codes) { 
    $view = new View(); 
    $view->setHeader('Access-Control-Allow-Origin', '*'); 
    $view->setData(array('type' => 'codes','data' => $this->_stringToArray($codes))); 
    $view->setFormat('json')->setHeader('Content-Type', 'application/json'); 
    return $this->handleView($view); 
} 

private function _stringToArray($string){ 
    return explode('+',$string); 
} 

Chức năng nào cho thấy là "bao phủ", chức năng riêng được gián tiếp bao phủ nhưng cho thấy màu đỏ trong PHPUnit báo cáo.

Test:

class ApiControllerTest extends WebTestCase { 

    public function test_getCodesAction(){ 
     $client = static::createClient(); 
     $client->request('GET', '/api/1+2+3'); 
     $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent()); 
    } 

} 

Đây chỉ là một ví dụ ngớ ngẩn tất nhiên, tôi có thể chỉ cũng bao gồm các explode() ngay trong hàm công cộng; Nhưng các bộ điều khiển tôi đang viết các bài kiểm tra để chứa các hàm riêng tư phức tạp hơn và có thể tái sử dụng để chuyển đổi dữ liệu theo nhiều cách phức tạp hơn (nhưng vẫn còn có hiệu ứng phụ miễn phí).

+1

Kiểm tra phương pháp tư nhân không phải là một vấn đề bằng cách riêng của mình - làm xét nghiệm như vậy không phải là một thực tế xấu. Nó có phương pháp riêng tư ở nơi đầu tiên được coi là có hại, bởi vì họ khó kiểm tra. – Narf

+1

@ narf, tôi không đồng ý với điều đó. thử nghiệm phương pháp riêng tư làm cho các xét nghiệm giòn và tôi sẽ xem xét nó một mùi mã xấu nếu bạn nghĩ rằng lựa chọn duy nhất của bạn là để nghỉ mát để thử nghiệm bằng cách phản ánh. Các phương thức riêng không có hại, chúng là một cách tốt để tổ chức mã bên trong một lớp. –

+1

@SamHolder Giòn là tốt hơn không có gì ... không có logic trong * có * một thử nghiệm là một thực tế xấu và bạn không thể thuyết phục tôi trong đó. :) Dù sao, những gì, làm thế nào và đến mức độ nào để kiểm tra chủ yếu là một chủ đề dựa trên ý kiến, vì vậy tôi thà đồng ý không đồng ý với bạn. :) – Narf

Trả lời

3

Trong Phpunit bạn có thể chỉ định Phương thức được bao gồm với chú thích đặc biệt, như được giải mã trong số doc.

Bạn có thể làm một cái gì đó như thế này:

class ApiControllerTest extends WebTestCase { 

     /** 
     * @covers ApiController::getCodesAction 
     * @covers ApiController::_stringToArray 
     */ 
     public function test_getCodesAction(){ 
      $client = static::createClient(); 
      $client->request('GET', '/api/1+2+3'); 
      $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent()); 
     } 

    } 

Hope trợ giúp này

+0

Tuyệt! Tôi đã không nhận ra rằng tôi có thể đặt nhiều chú thích @covers trên một chức năng kiểm tra. Tôi nghĩ rằng họ đã phải phù hợp với các chức năng công cộng! Tôi đã kiểm tra nó, và cũng phát hiện ra rằng nếu một chi nhánh trong một chức năng riêng tư là hoàn toàn dư thừa, do đó, nó đã được trả hết! – Fx32

+0

Hi @Feroxium bạn được chào đón! – Matteo

+4

Cool!?! Mát mẻ!?!?!?! nếu đây là giải pháp đúng thì chắc chắn tất cả các bạn đều muốn tìm việc mới từ PHP? Tôi không thể tin bất cứ ai nghĩ rằng giải pháp này là một ý tưởng tốt. Điều gì sẽ xảy ra nếu bạn cấu trúc lại mã để đổi tên phương thức? bây giờ tôi phải thay đổi chú thích trong các bình luận? Tôi thà bắn bản thân mình. –

Các vấn đề liên quan